Skip to content

Conversation

@matt-aitken
Copy link
Member

Summary

  • Add nullable projectId field to TaskScheduleInstance.
  • Create an index for TaskScheduleInstance.environmentId (added only if it doesn’t exist, handled concurrently).
  • Ensure TaskScheduleInstance.projectId is set everywhere in the codebase.

Backfilling projectIds, once this is live

UPDATE "TaskScheduleInstance" tsi
SET "projectId" = ts."projectId"
FROM "TaskSchedule" ts
WHERE tsi."taskScheduleId" = ts."id";

@changeset-bot
Copy link

changeset-bot bot commented Jan 15, 2026

⚠️ No Changeset found

Latest commit: 5e60aa2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

Walkthrough

These changes extend the TaskScheduleInstance entity to include a projectId field, establishing a relationship with the Project table. The database schema is updated with a new projectId column, a foreign key constraint referencing the Project table, and an index on the environmentId column. The application layer is modified to propagate projectId when creating or updating task schedule instances. Test files are updated to include projectId in test data creation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is missing several required sections from the template including the issue reference, checklist, testing steps, changelog, and screenshots sections. Fill in the PR description template with: issue reference (Closes #), completed checklist items, testing procedures, structured changelog, and any relevant screenshots.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add TaskScheduleInstance projectId' clearly and concisely summarizes the main change: adding a projectId field to TaskScheduleInstance.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa69b90 and 5e60aa2.

📒 Files selected for processing (7)
  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
  • internal-packages/database/prisma/migrations/20260115125846_add_project_id_to_task_schedule_instance/migration.sql
  • internal-packages/database/prisma/migrations/20260115130417_taskscheduleinstance_environmentid_index/migration.sql
  • internal-packages/database/prisma/schema.prisma
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

**/*.{ts,tsx}: Always import tasks from @trigger.dev/sdk, never use @trigger.dev/sdk/v3 or deprecated client.defineJob pattern
Every Trigger.dev task must be exported and have a unique id property with no timeouts in the run function

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Import from @trigger.dev/core using subpaths only, never import from root

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Access environment variables via env export from apps/webapp/app/env.server.ts, never use process.env directly

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
apps/webapp/app/v3/services/**/*.server.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Organize services in the webapp following the pattern app/v3/services/*/*.server.ts

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)

**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier before committing

Files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
internal-packages/database/prisma/migrations/**/*.sql

📄 CodeRabbit inference engine (CLAUDE.md)

internal-packages/database/prisma/migrations/**/*.sql: When editing the Prisma schema, remove extraneous migration lines related to specific tables: _BackgroundWorkerToBackgroundWorkerFile, _BackgroundWorkerToTaskQueue, _TaskRunToTaskRunTag, _WaitpointRunConnections, _completedWaitpoints, SecretStore_key_idx, and unrelated TaskRun indexes
Database indexes must use CONCURRENTLY to avoid table locks and must be in their own separate migration file

Files:

  • internal-packages/database/prisma/migrations/20260115130417_taskscheduleinstance_environmentid_index/migration.sql
  • internal-packages/database/prisma/migrations/20260115125846_add_project_id_to_task_schedule_instance/migration.sql
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use vitest for all tests in the Trigger.dev repository

Files:

  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptive describe and it blocks
Tests should avoid mocks or stubs and use the helpers from @internal/testcontainers when Redis or Postgres are needed
Use vitest for running unit tests

**/*.test.{ts,tsx,js,jsx}: Use vitest exclusively for testing and never mock anything - use testcontainers instead
Place test files next to source files with naming pattern: source file (e.g., MyService.ts) → MyService.test.ts

Files:

  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use testcontainers helpers (redisTest, postgresTest, containerTest) from @internal/testcontainers for Redis/PostgreSQL testing instead of mocks

Files:

  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
🧠 Learnings (8)
📚 Learning: 2026-01-15T11:50:06.044Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.044Z
Learning: Applies to internal-packages/database/prisma/migrations/**/*.sql : When editing the Prisma schema, remove extraneous migration lines related to specific tables: `_BackgroundWorkerToBackgroundWorkerFile`, `_BackgroundWorkerToTaskQueue`, `_TaskRunToTaskRunTag`, `_WaitpointRunConnections`, `_completedWaitpoints`, `SecretStore_key_idx`, and unrelated `TaskRun` indexes

Applied to files:

  • internal-packages/database/prisma/schema.prisma
  • internal-packages/database/prisma/migrations/20260115130417_taskscheduleinstance_environmentid_index/migration.sql
  • internal-packages/database/prisma/migrations/20260115125846_add_project_id_to_task_schedule_instance/migration.sql
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL

Applied to files:

  • internal-packages/database/prisma/schema.prisma
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach cron schedules declaratively using the `cron` property or imperatively using `schedules.create()`

Applied to files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schedules.task()` for scheduled/cron tasks instead of regular `task()`

Applied to files:

  • apps/webapp/app/v3/services/createBackgroundWorker.server.ts
  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
  • internal-packages/schedule-engine/test/scheduleRecovery.test.ts
  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
📚 Learning: 2026-01-15T11:50:06.044Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.044Z
Learning: Applies to internal-packages/database/prisma/migrations/**/*.sql : Database indexes must use CONCURRENTLY to avoid table locks and must be in their own separate migration file

Applied to files:

  • internal-packages/database/prisma/migrations/20260115130417_taskscheduleinstance_environmentid_index/migration.sql
  • internal-packages/database/prisma/migrations/20260115125846_add_project_id_to_task_schedule_instance/migration.sql
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
📚 Learning: 2026-01-15T11:50:06.044Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.044Z
Learning: Applies to **/*.{ts,tsx} : Always import tasks from `trigger.dev/sdk`, never use `trigger.dev/sdk/v3` or deprecated `client.defineJob` pattern

Applied to files:

  • apps/webapp/app/v3/services/upsertTaskSchedule.server.ts
📚 Learning: 2026-01-08T15:57:09.323Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/otel-metrics.mdc:0-0
Timestamp: 2026-01-08T15:57:09.323Z
Learning: Reference the schedule engine (internal-packages/schedule-engine/src/engine/index.ts) as a good example of implementing low-cardinality metric attributes

Applied to files:

  • internal-packages/schedule-engine/test/scheduleEngine.test.ts
🔇 Additional comments (11)
internal-packages/database/prisma/schema.prisma (2)

407-408: LGTM!

The taskScheduleInstances relation on Project is correctly defined and enables querying all schedule instances for a project.


1949-1962: LGTM!

The projectId field and relation are correctly defined as nullable, which supports the backfill strategy. The @@index([environmentId]) declaration aligns with the concurrent index migration file. The cascade behavior is appropriate for maintaining referential integrity.

internal-packages/schedule-engine/test/scheduleRecovery.test.ts (3)

78-85: LGTM!

The projectId field is correctly added to the test data, aligning with the schema changes.


184-191: LGTM!

Test data correctly includes projectId.


294-301: LGTM!

Test data correctly includes projectId for all schedule instances created in the loop.

internal-packages/schedule-engine/test/scheduleEngine.test.ts (1)

92-99: LGTM!

The projectId field is correctly added to the test data, maintaining consistency with the schema changes and other test files.

internal-packages/database/prisma/migrations/20260115130417_taskscheduleinstance_environmentid_index/migration.sql (1)

1-2: LGTM!

The migration correctly uses CREATE INDEX CONCURRENTLY IF NOT EXISTS to avoid table locks during index creation, and is properly isolated in its own migration file. Based on learnings, this follows the required database migration guidelines.

apps/webapp/app/v3/services/upsertTaskSchedule.server.ts (2)

108-128: LGTM!

The projectId is correctly propagated to the new TaskScheduleInstance, maintaining consistency with the parent TaskSchedule.


183-203: LGTM!

When creating new instances during schedule updates, the projectId is correctly sourced from existingSchedule.projectId, maintaining data consistency.

apps/webapp/app/v3/services/createBackgroundWorker.server.ts (1)

592-604: LGTM!

The projectId is correctly propagated from the environment when creating new declarative schedule instances, ensuring consistency with the database schema update.

internal-packages/database/prisma/migrations/20260115125846_add_project_id_to_task_schedule_instance/migration.sql (1)

1-16: LGTM - Well-structured migration with proper idempotency.

The migration correctly:

  • Uses IF NOT EXISTS for both the column addition and foreign key constraint
  • Keeps the column nullable to support the backfill strategy
  • Separates the index creation (environmentId) into its own migration file with CREATE INDEX CONCURRENTLY, complying with coding guidelines

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@matt-aitken matt-aitken marked this pull request as draft January 15, 2026 14:13
@vibe-kanban-cloud
Copy link

Review Complete

Your review story is ready!

View Story

Comment !reviewfast on this PR to re-generate the story.

@matt-aitken matt-aitken marked this pull request as ready for review January 15, 2026 14:34
@matt-aitken matt-aitken merged commit b696bbb into main Jan 15, 2026
32 checks passed
@matt-aitken matt-aitken deleted the taskscheduleinstance-projectid branch January 15, 2026 15:06
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.

3 participants