Files
spoon/packages/backend/convex/spoonCommits.ts
T
Gabriel Brown 2dfa97ee4f
Build and Push Next App / quality (push) Failing after 48s
Build and Push Next App / build-next (push) Has been skipped
Add agent workflows & stuff
2026-06-21 21:15:15 -05:00

100 lines
2.7 KiB
TypeScript

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 };
},
});