Add TaskScheduleInstance projectId (#2897)

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

```sql
UPDATE "TaskScheduleInstance" tsi
SET "projectId" = ts."projectId"
FROM "TaskSchedule" ts
WHERE tsi."taskScheduleId" = ts."id";
```
This commit is contained in:
Matt Aitken
2026-01-15 15:06:52 +00:00
committed by GitHub
parent aa69b9027d
commit b696bbb1df
7 changed files with 32 additions and 2 deletions
@@ -593,6 +593,7 @@ export async function syncDeclarativeSchedules(
create: [
{
environmentId: environment.id,
projectId: environment.projectId,
},
],
},
@@ -109,6 +109,7 @@ export class UpsertTaskScheduleService extends BaseService {
data: {
taskScheduleId: scheduleRecord.id,
environmentId,
projectId,
},
include: {
environment: {
@@ -183,6 +184,7 @@ export class UpsertTaskScheduleService extends BaseService {
data: {
taskScheduleId: scheduleRecord.id,
environmentId,
projectId: existingSchedule.projectId,
},
include: {
environment: {
@@ -0,0 +1,16 @@
-- AlterTable
ALTER TABLE "public"."TaskScheduleInstance"
ADD COLUMN IF NOT EXISTS "projectId" TEXT;
-- AddForeignKey
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'TaskScheduleInstance_projectId_fkey'
) THEN
ALTER TABLE "public"."TaskScheduleInstance"
ADD CONSTRAINT "TaskScheduleInstance_projectId_fkey"
FOREIGN KEY ("projectId") REFERENCES "public"."Project" ("id")
ON DELETE CASCADE ON UPDATE CASCADE;
END IF;
END $$;
@@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX CONCURRENTLY IF NOT EXISTS "TaskScheduleInstance_environmentId_idx" ON "public"."TaskScheduleInstance" ("environmentId");
@@ -404,7 +404,8 @@ model Project {
connectedGithubRepository ConnectedGithubRepository?
customerQueries CustomerQuery[]
buildSettings Json?
buildSettings Json?
taskScheduleInstances TaskScheduleInstance[]
}
enum ProjectVersion {
@@ -589,7 +590,7 @@ model TaskRun {
/// Debounce options: { key: string, delay: string, createdAt: Date }
debounce Json?
taskIdentifier String
taskIdentifier String
isTest Boolean @default(false)
@@ -1945,6 +1946,9 @@ model TaskScheduleInstance {
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -1955,6 +1959,7 @@ model TaskScheduleInstance {
//you can only have a schedule attached to each environment once
@@unique([taskScheduleId, environmentId])
@@index([environmentId])
}
model RuntimeEnvironmentSession {
@@ -93,6 +93,7 @@ describe("ScheduleEngine Integration", () => {
data: {
taskScheduleId: taskSchedule.id,
environmentId: environment.id,
projectId: project.id,
active: true,
},
});
@@ -79,6 +79,7 @@ describe("Schedule Recovery", () => {
data: {
taskScheduleId: taskSchedule.id,
environmentId: environment.id,
projectId: project.id,
active: true,
},
});
@@ -184,6 +185,7 @@ describe("Schedule Recovery", () => {
data: {
taskScheduleId: taskSchedule.id,
environmentId: environment.id,
projectId: project.id,
active: true,
},
});
@@ -293,6 +295,7 @@ describe("Schedule Recovery", () => {
data: {
taskScheduleId: taskSchedule.id,
environmentId: environment.id,
projectId: project.id,
active: true,
},
});