Skip to content

fix(scheduled-tasks): fix scheduled tasks schema validation#5091

Merged
Sg312 merged 2 commits into
stagingfrom
dev
Jun 16, 2026
Merged

fix(scheduled-tasks): fix scheduled tasks schema validation#5091
Sg312 merged 2 commits into
stagingfrom
dev

Conversation

@Sg312

@Sg312 Sg312 commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fix request validation bug with scheduled tasks in the mship stream

Type of Change

  • Bug fix

Testing

Manual

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 16, 2026 5:05am

Request Review

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a request-validation contention bug where opening a scheduled-task artifact in the mothership viewer triggered a full workspace-schedule list fetch that competed with the chat stream. The fix introduces a dedicated GET /api/schedules/[id] endpoint and useScheduleById hook for lightweight single-schedule reads, and adds scheduledtask as a supported context kind in the copilot chat pipeline.

  • Adds getScheduleByIdContract and the corresponding route handler with proper auth via the existing fetchAndAuthorize helper; replaces useWorkspaceSchedules + useMemo find with useScheduleById in EmbeddedScheduledTask.
  • Adds resolveScheduledTaskResource in process-contents.ts that scopes to sourceType='job' and sourceWorkspaceId ownership before emitting a VFS path pointer, keeping the agent context read lightweight.

Confidence Score: 4/5

Safe to merge — authorization is correctly enforced on the new GET endpoint and the copilot context resolver validates workspace ownership before returning any data.

The new endpoint and hook are both correct and well-scoped. Two minor issues hold the score below the max: the GET handler queries the database twice for the same row (auth partial-select then full-select), and the EmbeddedScheduledTaskProps interface retains a workspaceId field that the component no longer reads, leaving a dead prop still required at every call site.

apps/sim/app/api/schedules/[id]/route.ts (double DB query in the GET handler); apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx (stale workspaceId prop in EmbeddedScheduledTaskProps)

Important Files Changed

Filename Overview
apps/sim/app/api/schedules/[id]/route.ts Adds GET handler for single-schedule lookup by ID with proper auth via fetchAndAuthorize; performs two DB queries for one read (auth query + full-row query).
apps/sim/lib/api/contracts/schedules.ts Adds getScheduleByIdContract for GET /api/schedules/[id] with correct params schema and response shape. Straightforward and consistent with existing contract definitions.
apps/sim/hooks/queries/schedules.ts Adds useScheduleById hook with correct query key, enabled guard, and 30s staleTime; cleanly replaces the workspace-list lookup in the mothership viewer.
apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx Switches EmbeddedScheduledTask to useScheduleById, but workspaceId remains in the EmbeddedScheduledTaskProps interface and is still passed at the call site even though the component no longer uses it.
apps/sim/lib/copilot/chat/process-contents.ts Adds resolveScheduledTaskResource that correctly scopes to sourceType='job' and verifies sourceWorkspaceId ownership before returning a VFS path pointer.
apps/sim/lib/copilot/chat/post.ts Adds 'scheduledtask' to ResourceAttachmentSchema and ChatContextSchema enums, and scheduleId as an optional field. Clean and consistent with the existing pattern.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant UI as Mothership UI
    participant Hook as useScheduleById
    participant API as GET /api/schedules/[id]
    participant Auth as fetchAndAuthorize
    participant DB as Database

    UI->>Hook: scheduleId
    Hook->>API: "GET /api/schedules/{id}"
    API->>Auth: fetchAndAuthorize(scheduleId, userId, 'read')
    Auth->>DB: "SELECT partial row WHERE id=? AND archivedAt IS NULL"
    DB-->>Auth: partial ScheduleRow
    Auth-->>API: "{ schedule, workspaceId }"
    API->>DB: "SELECT * WHERE id=? AND archivedAt IS NULL"
    DB-->>API: full WorkflowSchedule row
    API-->>Hook: "{ schedule: fullRow }"
    Hook-->>UI: schedule data

    Note over UI,DB: copilot chat path
    UI->>API: "POST /api/copilot/chat (kind='scheduledtask')"
    API->>DB: resolveScheduledTaskResource(scheduleId, workspaceId)
    Note right of DB: filters sourceType='job' and sourceWorkspaceId
    DB-->>API: "{ id, jobTitle }"
    API-->>UI: "VFS path jobs/{title}/meta.json"
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant UI as Mothership UI
    participant Hook as useScheduleById
    participant API as GET /api/schedules/[id]
    participant Auth as fetchAndAuthorize
    participant DB as Database

    UI->>Hook: scheduleId
    Hook->>API: "GET /api/schedules/{id}"
    API->>Auth: fetchAndAuthorize(scheduleId, userId, 'read')
    Auth->>DB: "SELECT partial row WHERE id=? AND archivedAt IS NULL"
    DB-->>Auth: partial ScheduleRow
    Auth-->>API: "{ schedule, workspaceId }"
    API->>DB: "SELECT * WHERE id=? AND archivedAt IS NULL"
    DB-->>API: full WorkflowSchedule row
    API-->>Hook: "{ schedule: fullRow }"
    Hook-->>UI: schedule data

    Note over UI,DB: copilot chat path
    UI->>API: "POST /api/copilot/chat (kind='scheduledtask')"
    API->>DB: resolveScheduledTaskResource(scheduleId, workspaceId)
    Note right of DB: filters sourceType='job' and sourceWorkspaceId
    DB-->>API: "{ id, jobTitle }"
    API-->>UI: "VFS path jobs/{title}/meta.json"
Loading

Comments Outside Diff (1)

  1. apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx, line 691-694 (link)

    P2 The workspaceId field is still declared on the interface and passed by the call site (line 193), but the component no longer reads it. The dead prop adds noise and forces every future caller to supply a value it will never consume.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "fix(scheduled-tasks): fix schema rejecti..." | Re-trigger Greptile

Comment thread apps/sim/app/api/schedules/[id]/route.ts Outdated
@Sg312 Sg312 changed the title feat(scheduled-tasks): add scheduled tasks to mship fix(scheduled-tasks): fix scheduled tasks schema validation Jun 16, 2026
@Sg312 Sg312 merged commit 6cbaf42 into staging Jun 16, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant