import { v } from 'convex/values'; import { internalMutation, internalQuery, query } from './_generated/server'; import { getOwnedSpoon, getRequiredUserId } from './model'; const side = v.union(v.literal('upstream'), v.literal('fork')); export const listForSpoon = query({ args: { spoonId: v.id('spoons'), side: v.optional(side), limit: v.optional(v.number()), }, handler: async (ctx, { spoonId, side, limit }) => { const ownerId = await getRequiredUserId(ctx); await getOwnedSpoon(ctx, spoonId, ownerId); if (side) { return await ctx.db .query('spoonCommits') .withIndex('by_spoon_side', (q) => q.eq('spoonId', spoonId).eq('side', side), ) .order('desc') .take(limit ?? 100); } const commits = await ctx.db .query('spoonCommits') .withIndex('by_owner', (q) => q.eq('ownerId', ownerId)) .order('desc') .collect(); return commits .filter((commit) => commit.spoonId === spoonId) .slice(0, limit ?? 100); }, }); export const listInternal = internalQuery({ args: { spoonId: v.id('spoons'), ownerId: v.id('users'), side, limit: v.optional(v.number()), }, handler: async (ctx, { spoonId, ownerId, side, limit }) => { const rows = await ctx.db .query('spoonCommits') .withIndex('by_spoon_side', (q) => q.eq('spoonId', spoonId).eq('side', side), ) .order('desc') .take(limit ?? 100); return rows.filter((row) => row.ownerId === ownerId); }, }); export const replaceForSpoon = internalMutation({ args: { spoonId: v.id('spoons'), ownerId: v.id('users'), side, commits: v.array( v.object({ sha: v.string(), message: v.string(), authorName: v.optional(v.string()), authorEmail: v.optional(v.string()), authorLogin: v.optional(v.string()), committedAt: v.optional(v.number()), htmlUrl: v.optional(v.string()), filesChanged: v.optional(v.number()), additions: v.optional(v.number()), deletions: v.optional(v.number()), }), ), }, handler: async (ctx, { spoonId, ownerId, side, commits }) => { const existing = await ctx.db .query('spoonCommits') .withIndex('by_spoon_side', (q) => q.eq('spoonId', spoonId).eq('side', side), ) .collect(); await Promise.all(existing.map((commit) => ctx.db.delete(commit._id))); const now = Date.now(); await Promise.all( commits.map((commit) => ctx.db.insert('spoonCommits', { spoonId, ownerId, side, ...commit, createdAt: now, updatedAt: now, }), ), ); return { success: true }; }, });