diff --git a/convex/migrations.ts b/convex/migrations.ts index 50869b6c..92f792e6 100644 --- a/convex/migrations.ts +++ b/convex/migrations.ts @@ -36,7 +36,6 @@ const APPLY_SKILL_INSTALL_BACKFILL_CONFIRM = "apply-skill-install-backfill"; const APPLY_NVIDIA_GITHUB_DOWNLOAD_BACKFILL_CONFIRM = "apply-nvidia-github-download-backfill"; const BACKFILL_PLUGIN_MANIFEST_SUMMARIES_CONFIRM = "backfill-plugin-manifest-summaries"; const RECOVER_SUSPICIOUS_PUBLISH_ATTEMPTS_CONFIRM = "recover-suspicious-publish-attempts"; -const CLEAN_STALE_TEST_PREPUBLICATION_CONFIRM = "clean-stale-test-prepublication"; const SKILL_STAT_EVENTS_CURSOR_KEY = "skill_stat_events"; const MAX_PENDING_SKILL_STAT_EVENTS_PER_SKILL = 1_000; const PLUGIN_PACKAGE_FAMILIES = ["code-plugin", "bundle-plugin"] as const; @@ -83,159 +82,6 @@ export const migrations = new Migrations(components.migrations, { defaultBatchSize: 25, }); -type StaleTestPrepublicationPreview = { - skillVersions: string[]; - packageReleases: string[]; - publishAttempts: string[]; -}; - -const STALE_TEST_PREPUBLICATION_SKILL_VERSION_IDS = [ - "k9744ms64hqgt2gsbrqecgyan18an1sy", - "k977n0780pgddbyq4amzm2c7qs8anp42", -] as const; -const STALE_TEST_PREPUBLICATION_PACKAGE_RELEASE_IDS = ["rd73d4smq092bxqtdzw4wbpx6d8anphq"] as const; -const STALE_TEST_PREPUBLICATION_PUBLISH_ATTEMPT_IDS = [ - "qd7fe83x22dtevcserrr5yvp698anerg", - "qd786d4wehvdz29htqwnh289g98am4tm", - "qd792fjf2ndphp0357j51bxvp98amkeb", -] as const; -const staleTestPrepublicationSkillVersionIds = new Set( - STALE_TEST_PREPUBLICATION_SKILL_VERSION_IDS, -); -const staleTestPrepublicationPackageReleaseIds = new Set( - STALE_TEST_PREPUBLICATION_PACKAGE_RELEASE_IDS, -); -const staleTestPrepublicationPublishAttemptIds = new Set( - STALE_TEST_PREPUBLICATION_PUBLISH_ATTEMPT_IDS, -); - -export const cleanupStaleTestPrepublicationSkillVersions = migrations.define({ - table: "skillVersions", - batchSize: 200, - migrateOne: async (ctx, version) => { - if ( - !staleTestPrepublicationSkillVersionIds.has(version._id) || - (version.publicationStatus === undefined && - version.publishAttemptId === undefined && - version.pendingPublication === undefined) - ) { - return; - } - await ctx.db.patch(version._id, { - publicationStatus: undefined, - publishAttemptId: undefined, - pendingPublication: undefined, - }); - }, -}); - -export const cleanupStaleTestPrepublicationPackageReleases = migrations.define({ - table: "packageReleases", - batchSize: 200, - migrateOne: async (ctx, release) => { - if ( - !staleTestPrepublicationPackageReleaseIds.has(release._id) || - (release.publicationStatus === undefined && - release.publishAttemptId === undefined && - release.pendingPublication === undefined) - ) { - return; - } - await ctx.db.patch(release._id, { - publicationStatus: undefined, - publishAttemptId: undefined, - pendingPublication: undefined, - }); - }, -}); - -export const cleanupStaleTestPrepublicationPublishAttempts = migrations.define({ - table: "publishAttempts", - batchSize: 200, - migrateOne: async (ctx, attempt) => { - if ( - !staleTestPrepublicationPublishAttemptIds.has(attempt._id) || - (attempt.skillId === undefined && - attempt.skillVersionId === undefined && - attempt.packageId === undefined && - attempt.packageReleaseId === undefined && - attempt.createdNewParent === undefined && - attempt.clawpackStorageId === undefined && - attempt.scanContext === undefined) - ) { - return; - } - await ctx.db.patch(attempt._id, { - skillId: undefined, - skillVersionId: undefined, - packageId: undefined, - packageReleaseId: undefined, - createdNewParent: undefined, - clawpackStorageId: undefined, - scanContext: undefined, - }); - }, -}); - -export const previewStaleTestPrepublicationInternal = internalQuery({ - args: {}, - returns: v.object({ - skillVersions: v.array(v.string()), - packageReleases: v.array(v.string()), - publishAttempts: v.array(v.string()), - }), - handler: async (ctx): Promise => { - const skillVersions = await Promise.all( - STALE_TEST_PREPUBLICATION_SKILL_VERSION_IDS.map((id) => - ctx.db.get(id as Id<"skillVersions">), - ), - ); - const packageReleases = await Promise.all( - STALE_TEST_PREPUBLICATION_PACKAGE_RELEASE_IDS.map((id) => - ctx.db.get(id as Id<"packageReleases">), - ), - ); - const publishAttempts = await Promise.all( - STALE_TEST_PREPUBLICATION_PUBLISH_ATTEMPT_IDS.map((id) => - ctx.db.get(id as Id<"publishAttempts">), - ), - ); - return { - skillVersions: skillVersions - .filter( - (version): version is Doc<"skillVersions"> => - version !== null && - (version.publicationStatus !== undefined || - version.publishAttemptId !== undefined || - version.pendingPublication !== undefined), - ) - .map((version) => version._id), - packageReleases: packageReleases - .filter( - (release): release is Doc<"packageReleases"> => - release !== null && - (release.publicationStatus !== undefined || - release.publishAttemptId !== undefined || - release.pendingPublication !== undefined), - ) - .map((release) => release._id), - publishAttempts: publishAttempts - .filter( - (attempt): attempt is Doc<"publishAttempts"> => - attempt !== null && - (attempt.skillId !== undefined || - attempt.skillVersionId !== undefined || - attempt.packageId !== undefined || - attempt.packageReleaseId !== undefined || - attempt.createdNewParent !== undefined || - attempt.clawpackStorageId !== undefined || - attempt.scanContext !== undefined), - ) - .map((attempt) => attempt._id), - }; - }, -}); - type SuspiciousPublishAttemptRecoveryClassification = | "replay_missing" | "replay_identical" @@ -1506,61 +1352,6 @@ export const runSuspiciousPublishAttemptRecovery: ReturnType = internalAction({ - args: { - dryRun: v.optional(v.boolean()), - confirm: v.optional(v.string()), - }, - returns: v.object({ - ok: v.literal(true), - dryRun: v.boolean(), - confirmRequired: v.optional(v.string()), - before: v.object({ - skillVersions: v.array(v.string()), - packageReleases: v.array(v.string()), - publishAttempts: v.array(v.string()), - }), - after: v.object({ - skillVersions: v.array(v.string()), - packageReleases: v.array(v.string()), - publishAttempts: v.array(v.string()), - }), - }), - handler: async (ctx, args) => { - const dryRun = args.dryRun !== false; - if (!dryRun && args.confirm !== CLEAN_STALE_TEST_PREPUBLICATION_CONFIRM) { - throw new ConvexError(`Pass confirm="${CLEAN_STALE_TEST_PREPUBLICATION_CONFIRM}" to apply.`); - } - const before: StaleTestPrepublicationPreview = await ctx.runQuery( - internal.migrations.previewStaleTestPrepublicationInternal, - {}, - ); - const migrationFunctions = [ - internal.migrations.cleanupStaleTestPrepublicationSkillVersions, - internal.migrations.cleanupStaleTestPrepublicationPackageReleases, - internal.migrations.cleanupStaleTestPrepublicationPublishAttempts, - ] as const; - if (!dryRun) { - for (const fn of migrationFunctions) { - await runToCompletion(ctx, components.migrations, fn, { - cursor: null, - batchSize: 200, - }); - } - } - const after: StaleTestPrepublicationPreview = dryRun - ? before - : await ctx.runQuery(internal.migrations.previewStaleTestPrepublicationInternal, {}); - return { - ok: true as const, - dryRun, - confirmRequired: dryRun ? CLEAN_STALE_TEST_PREPUBLICATION_CONFIRM : undefined, - before, - after, - }; - }, -}); - export const runCatalogMetadataCanonicalization = internalAction({ args: { dryRun: v.optional(v.boolean()), diff --git a/convex/schema.ts b/convex/schema.ts index 9d4e34d0..82dfc56a 100644 --- a/convex/schema.ts +++ b/convex/schema.ts @@ -990,12 +990,6 @@ const skillSlugAliases = defineTable({ const skillVersions = defineTable({ skillId: v.id("skills"), version: v.string(), - // Temporary compatibility for stale Test data from an unmerged prepublication branch. - publicationStatus: v.optional( - v.union(v.literal("pending"), v.literal("published"), v.literal("blocked")), - ), - publishAttemptId: v.optional(v.id("publishAttempts")), - pendingPublication: v.optional(v.any()), fingerprint: v.optional(v.string()), sourceProvenance: v.optional( v.object({ @@ -1131,13 +1125,6 @@ const publishAttempts = defineTable({ ownerUserId: v.optional(v.id("users")), ownerPublisherId: v.optional(v.id("publishers")), sourceOwnerPublisherId: v.optional(v.id("publishers")), - // Temporary compatibility for stale Test data from an unmerged prepublication branch. - skillId: v.optional(v.id("skills")), - skillVersionId: v.optional(v.id("skillVersions")), - packageId: v.optional(v.id("packages")), - packageReleaseId: v.optional(v.id("packageReleases")), - createdNewParent: v.optional(v.boolean()), - clawpackStorageId: v.optional(v.id("_storage")), slug: v.string(), displayName: v.string(), version: v.string(), @@ -1150,7 +1137,6 @@ const publishAttempts = defineTable({ }), skillInsertArgs: v.optional(v.any()), packageInsertArgs: v.optional(v.any()), - scanContext: v.optional(v.any()), followup: v.optional( v.object({ skipWebhook: v.optional(v.boolean()), @@ -1650,12 +1636,6 @@ const packages = defineTable({ const packageReleases = defineTable({ packageId: v.id("packages"), version: v.string(), - // Temporary compatibility for stale Test data from an unmerged prepublication branch. - publicationStatus: v.optional( - v.union(v.literal("pending"), v.literal("published"), v.literal("blocked")), - ), - publishAttemptId: v.optional(v.id("publishAttempts")), - pendingPublication: v.optional(v.any()), changelog: v.string(), summary: v.optional(v.string()), icon: v.optional(v.string()),