import { v } from 'convex/values'; import { internalMutation, query } from './_generated/server'; import { getOwnedSpoon, getRequiredUserId } from './model'; const scope = v.union( v.literal('fork'), v.literal('upstream'), v.literal('from_fork_to_upstream'), ); const state = v.union( v.literal('open'), v.literal('closed'), v.literal('merged'), ); export const listForSpoon = query({ args: { spoonId: v.id('spoons'), scope: v.optional(scope), state: v.optional(state), limit: v.optional(v.number()), }, handler: async (ctx, args) => { const ownerId = await getRequiredUserId(ctx); await getOwnedSpoon(ctx, args.spoonId, ownerId); const requestedScope = args.scope; const rows = requestedScope ? await ctx.db .query('spoonPullRequests') .withIndex('by_spoon_scope', (q) => q.eq('spoonId', args.spoonId).eq('scope', requestedScope), ) .order('desc') .collect() : await ctx.db .query('spoonPullRequests') .withIndex('by_spoon', (q) => q.eq('spoonId', args.spoonId)) .order('desc') .collect(); return rows .filter((row) => !args.state || row.state === args.state) .slice(0, args.limit ?? 100); }, }); export const replaceForSpoon = internalMutation({ args: { spoonId: v.id('spoons'), ownerId: v.id('users'), scope, pullRequests: v.array( v.object({ githubId: v.number(), number: v.number(), repoFullName: v.string(), title: v.string(), state, draft: v.boolean(), authorLogin: v.optional(v.string()), baseRef: v.string(), headRef: v.string(), headRepoFullName: v.optional(v.string()), htmlUrl: v.string(), createdAtGithub: v.optional(v.number()), updatedAtGithub: v.optional(v.number()), mergedAtGithub: v.optional(v.number()), }), ), }, handler: async (ctx, { spoonId, ownerId, scope, pullRequests }) => { const existing = await ctx.db .query('spoonPullRequests') .withIndex('by_spoon_scope', (q) => q.eq('spoonId', spoonId).eq('scope', scope), ) .collect(); await Promise.all( existing.map((pullRequest) => ctx.db.delete(pullRequest._id)), ); const now = Date.now(); await Promise.all( pullRequests.map((pullRequest) => ctx.db.insert('spoonPullRequests', { spoonId, ownerId, scope, ...pullRequest, createdAt: now, updatedAt: now, }), ), ); return { success: true }; }, });