fix(sync): company-scope לג'ובים מתוזמנים — הפסקת בליעת-כשל (legal-ai #637) #11

Merged
chaim merged 1 commits from fix/637-scheduled-job-context into main 2026-08-26 13:13:48 +00:00
Owner

הבאג

sync-case-status נכשל בכל ריצה על legalApiBaseUrl unresolvedTypeError: fetch failed, לפני שהגיע ל-pickSyncTargetIssue. ובכל זאת plugin_job_runs.status = succeeded.

legalApiBaseUrl unresolved   : 3,082 מופעים בלוג
company context is required  : 98,571 מופעים
כתיבה אחרונה בפועל           : 2026-07-22

סיבת-השורש

מאז @paperclipai/server 2026.722.0 אין scope של חברה ב-runJobplugin-job-scheduler.js:184 שולח בלי companyId, ולכן כל ctx.config.get/ctx.issues.* נדחית ב-InvocationScopeDeniedError (-32005).

⚠️ התיקון החשוב מכולם — הפסקת הבליעה

ה-try/catch ב-worker.ts הוסר. runJobHandler מלוגג וזורק מחדש, כך שהמתזמר רושם status:"failed".

זה חשוב יותר מהתיקון עצמו: כל עוד הבליעה קיימת, כל תיקון עתידי נראה כמו הצלחה — וזה בדיוק מה שאיפשר ל-13,872 ריצות להיראות ירוקות בזמן ש-98,571 שגיאות הצטברו.

שתי הכרעות-תכנון

  1. זיהוי מבני, לא מחרוזתי — דחיית-scope מזוהה לפי err.code === -32005 ולא בהתאמת-מחרוזת על ההודעה, שיכולה להישבר בשקט אם המארח ינסח מחדש.
  2. memo ברמת-המודולLegalApi.request קורא ל-resolveBaseUrl() בכל בקשה; בלי ה-memo כל קריאת-כלי הייתה מוסיפה ctx.state.set (=upsert ל-Postgres) מיותר.

ו-company-scope.ts טהור בכוונה (כמו sync-target.ts) — ניתן לייבוא בטסט בלי להריץ runWorker.

בדיקות

node --test --experimental-strip-types src/*.test.ts
→ 29 pass · 0 fail
tsc --noEmit → exit 0

פריסה ⚠️

ריפו נפרד ואינו נטען מ-git: npm run buildהתקנת החבילה ל-/data/paperclip/plugins/node_modules/@marcusgroup/plugin-legal-ai/pm2 restart paperclip. לאמת שהמותקן התעדכן.

Invariants

כלל-הנדסה §6 (לב התיקון) · G2 (הפשטה אחת לכל הג'ובים) · G1 (נרמול במקור).

Closes #637 (ב-legal-ai)

## הבאג `sync-case-status` **נכשל בכל ריצה** על `legalApiBaseUrl unresolved` → `TypeError: fetch failed`, **לפני** שהגיע ל-`pickSyncTargetIssue`. ובכל זאת `plugin_job_runs.status = succeeded`. ``` legalApiBaseUrl unresolved : 3,082 מופעים בלוג company context is required : 98,571 מופעים כתיבה אחרונה בפועל : 2026-07-22 ``` ## סיבת-השורש מאז `@paperclipai/server` 2026.722.0 **אין scope של חברה ב-`runJob`** — `plugin-job-scheduler.js:184` שולח בלי `companyId`, ולכן כל `ctx.config.get`/`ctx.issues.*` נדחית ב-`InvocationScopeDeniedError` (`-32005`). ## ⚠️ התיקון החשוב מכולם — הפסקת הבליעה ה-`try/catch` ב-`worker.ts` הוסר. `runJobHandler` מלוגג **וזורק מחדש**, כך שהמתזמר רושם `status:"failed"`. **זה חשוב יותר מהתיקון עצמו:** כל עוד הבליעה קיימת, **כל תיקון עתידי נראה כמו הצלחה** — וזה בדיוק מה שאיפשר ל-13,872 ריצות להיראות ירוקות בזמן ש-98,571 שגיאות הצטברו. ## שתי הכרעות-תכנון 1. **זיהוי מבני, לא מחרוזתי** — דחיית-scope מזוהה לפי `err.code === -32005` ולא בהתאמת-מחרוזת על ההודעה, שיכולה להישבר בשקט אם המארח ינסח מחדש. 2. **memo ברמת-המודול** — `LegalApi.request` קורא ל-`resolveBaseUrl()` בכל בקשה; בלי ה-memo כל קריאת-כלי הייתה מוסיפה `ctx.state.set` (=upsert ל-Postgres) מיותר. ו-`company-scope.ts` **טהור בכוונה** (כמו `sync-target.ts`) — ניתן לייבוא בטסט בלי להריץ `runWorker`. ## בדיקות ``` node --test --experimental-strip-types src/*.test.ts → 29 pass · 0 fail tsc --noEmit → exit 0 ``` ## פריסה ⚠️ ריפו נפרד ואינו נטען מ-git: `npm run build` → **התקנת החבילה** ל-`/data/paperclip/plugins/node_modules/@marcusgroup/plugin-legal-ai/` → `pm2 restart paperclip`. **לאמת שהמותקן התעדכן.** ## Invariants **כלל-הנדסה §6** (לב התיקון) · **G2** (הפשטה אחת לכל הג'ובים) · **G1** (נרמול במקור). `Closes #637` (ב-legal-ai)
chaim added 1 commit 2026-08-26 13:13:38 +00:00
הג'וב `sync-case-status` נכשל בכל ריצה על `legalApiBaseUrl unresolved` →
`TypeError: fetch failed`, לפני שהגיע ל-`pickSyncTargetIssue` — ובכל זאת
`plugin_job_runs.status = succeeded`, כי ה-try/catch ב-worker.ts בלע את
הכישלון ל-logger.error. 3,082 מופעי `unresolved` ו-98,571 מופעי
`company context is required` בלוג; כתיבה אחרונה בפועל 2026-07-22.

סיבת-השורש: מאז @paperclipai/server 2026.722.0 אין scope של חברה ב-runJob
(plugin-job-scheduler.js:184 שולח בלי companyId), ולכן כל ctx.config.get /
ctx.issues.* נדחית ב-InvocationScopeDeniedError (-32005).

- `src/company-scope.ts` — הפשטה טהורה (כמו sync-target.ts, ניתנת לטסט בלי
  runWorker): פתרון base-URL עם cache ב-ctx.state + memo ברמת-המודול כדי
  לא לכתוב ל-Postgres בכל בקשה, וזיהוי **מבני** של דחיית-scope לפי
  `err.code` ולא התאמת-מחרוזת על ההודעה.
- `runJobHandler` מלוגג **וזורק מחדש** — המתזמר רושם `status:"failed"`
  במקום `succeeded`. ה-try/catch הבולע הוסר (כלל-הנדסה §6).
- כשה-scope אינו זמין: `CompanyScopeUnavailableError` מפורש במקום ניחוש.

Invariants: כלל-הנדסה §6 (אין בליעה שקטה — זה לב התיקון) · G2 (הפשטה אחת
לכל הג'ובים, לא טיפול פר-ג'וב) · G1 (נרמול במקור).

Closes #637
chaim merged commit 7cbb3d1c03 into main 2026-08-26 13:13:48 +00:00
chaim deleted branch fix/637-scheduled-job-context 2026-08-26 13:13:48 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ezer-mishpati/plugin-legal-ai#11