| 465 | db: WorkerDb, |
| 466 | owner: SecurityReviewOwner, |
| 467 | progress: SyncRunProgressWrite |
| 468 | ): Promise<{ written: boolean }> { |
| 469 | const progressJson = JSON.stringify(progress); |
| 470 | const completedReposJson = JSON.stringify(progress.completedRepos); |
| 471 | const rows = await db |
| 472 | .update(agent_configs) |
| 473 | .set({ |
| 474 | runtime_state: sql`jsonb_set( |
| 475 | COALESCE(${agent_configs.runtime_state}, '{}'::jsonb), |
| 476 | '{sync_run}', |
| 477 | ${progressJson}::jsonb || jsonb_build_object( |
| 478 | 'completedRepos', |
| 479 | ( |
| 480 | SELECT COALESCE(jsonb_agg(DISTINCT elem), '[]'::jsonb) |
| 481 | FROM jsonb_array_elements_text( |
| 482 | COALESCE(${agent_configs.runtime_state}->'sync_run'->'completedRepos', '[]'::jsonb) |
| 483 | || ${completedReposJson}::jsonb |
| 484 | ) AS elem |
| 485 | ) |
| 486 | ), |
| 487 | true |
| 488 | )`, |
| 489 | }) |
| 490 | .where( |
| 491 | and( |
| 492 | eq(agent_configs.agent_type, 'security_scan'), |
| 493 | eq(agent_configs.platform, 'github'), |
| 494 | ownerFilter(owner), |
| 495 | sql`${agent_configs.runtime_state}->'sync_lease'->>'runId' = ${progress.runId}`, |
| 496 | sql`${agent_configs.runtime_state}->'sync_run'->>'runId' = ${progress.runId}`, |
| 497 | sql`COALESCE((${agent_configs.runtime_state}->'sync_lease'->>'chunkIndex')::int, -1) <= ${progress.chunkIndex}`, |
| 498 | sql`(${agent_configs.runtime_state}->'sync_run'->'chunkIndex' IS NULL OR (${agent_configs.runtime_state}->'sync_run'->>'chunkIndex')::int <= ${progress.chunkIndex})` |
| 499 | ) |
| 500 | ) |
| 501 | .returning({ id: agent_configs.id }); |
| 502 | return { written: rows.length > 0 }; |
| 503 | } |
| 504 | |
| 505 | export async function clearSyncRunProgress( |
| 506 | db: WorkerDb, |
| 507 | owner: SecurityReviewOwner, |
| 508 | runId: string, |
| 509 | chunkIndex: number |
| 510 | ): Promise<{ cleared: boolean }> { |
| 511 | const rows = await db |
| 512 | .update(agent_configs) |
| 513 | .set({ |
| 514 | runtime_state: sql`COALESCE(${agent_configs.runtime_state}, '{}'::jsonb) - 'sync_run'`, |
| 515 | }) |
| 516 | .where( |
| 517 | and( |
| 518 | eq(agent_configs.agent_type, 'security_scan'), |
| 519 | eq(agent_configs.platform, 'github'), |
| 520 | ownerFilter(owner), |
| 521 | sql`${agent_configs.runtime_state}->'sync_run'->>'runId' = ${runId}`, |
| 522 | sql`${agent_configs.runtime_state}->'sync_lease'->>'runId' = ${runId}`, |
| 523 | sql`COALESCE((${agent_configs.runtime_state}->'sync_lease'->>'chunkIndex')::int, -1) <= ${chunkIndex}`, |
| 524 | sql`(${agent_configs.runtime_state}->'sync_run'->'chunkIndex' IS NULL OR (${agent_configs.runtime_state}->'sync_run'->>'chunkIndex')::int <= ${chunkIndex})` |