Add agent workflows & stuff
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import { ConvexError, v } from 'convex/values';
|
||||
|
||||
import type { Doc, Id } from './_generated/dataModel';
|
||||
import { internalMutation, internalQuery, query } from './_generated/server';
|
||||
import { getOwnedSpoon, getRequiredUserId } from './model';
|
||||
|
||||
const syncStatus = v.union(
|
||||
v.literal('up_to_date'),
|
||||
v.literal('behind'),
|
||||
v.literal('ahead'),
|
||||
v.literal('diverged'),
|
||||
v.literal('unknown'),
|
||||
);
|
||||
|
||||
export const deriveSyncStatus = ({
|
||||
upstreamAheadBy,
|
||||
forkAheadBy,
|
||||
}: {
|
||||
upstreamAheadBy: number;
|
||||
forkAheadBy: number;
|
||||
}): Doc<'spoonRepositoryStates'>['status'] => {
|
||||
if (upstreamAheadBy === 0 && forkAheadBy === 0) return 'up_to_date';
|
||||
if (upstreamAheadBy > 0 && forkAheadBy === 0) return 'behind';
|
||||
if (upstreamAheadBy === 0 && forkAheadBy > 0) return 'ahead';
|
||||
if (upstreamAheadBy > 0 && forkAheadBy > 0) return 'diverged';
|
||||
return 'unknown';
|
||||
};
|
||||
|
||||
export const getForSpoon = query({
|
||||
args: { spoonId: v.id('spoons') },
|
||||
handler: async (ctx, { spoonId }) => {
|
||||
const ownerId = await getRequiredUserId(ctx);
|
||||
await getOwnedSpoon(ctx, spoonId, ownerId);
|
||||
return await ctx.db
|
||||
.query('spoonRepositoryStates')
|
||||
.withIndex('by_spoon', (q) => q.eq('spoonId', spoonId))
|
||||
.first();
|
||||
},
|
||||
});
|
||||
|
||||
export const listForOwner = query({
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
const ownerId = await getRequiredUserId(ctx);
|
||||
return await ctx.db
|
||||
.query('spoonRepositoryStates')
|
||||
.withIndex('by_owner', (q) => q.eq('ownerId', ownerId))
|
||||
.collect();
|
||||
},
|
||||
});
|
||||
|
||||
export const getInternal = internalQuery({
|
||||
args: { spoonId: v.id('spoons'), ownerId: v.id('users') },
|
||||
handler: async (ctx, { spoonId, ownerId }) => {
|
||||
const state = await ctx.db
|
||||
.query('spoonRepositoryStates')
|
||||
.withIndex('by_spoon', (q) => q.eq('spoonId', spoonId))
|
||||
.first();
|
||||
if (state && state.ownerId !== ownerId) {
|
||||
throw new ConvexError('Repository state ownership mismatch.');
|
||||
}
|
||||
return state;
|
||||
},
|
||||
});
|
||||
|
||||
export const upsert = internalMutation({
|
||||
args: {
|
||||
spoonId: v.id('spoons'),
|
||||
ownerId: v.id('users'),
|
||||
upstreamFullName: v.string(),
|
||||
forkFullName: v.string(),
|
||||
upstreamDefaultBranch: v.string(),
|
||||
forkDefaultBranch: v.string(),
|
||||
upstreamHeadSha: v.optional(v.string()),
|
||||
forkHeadSha: v.optional(v.string()),
|
||||
mergeBaseSha: v.optional(v.string()),
|
||||
upstreamAheadBy: v.number(),
|
||||
forkAheadBy: v.number(),
|
||||
status: syncStatus,
|
||||
openForkPullRequestCount: v.number(),
|
||||
openUpstreamPullRequestCount: v.number(),
|
||||
lastCommitAt: v.optional(v.number()),
|
||||
rawCompareUrl: v.optional(v.string()),
|
||||
},
|
||||
handler: async (ctx, args): Promise<Id<'spoonRepositoryStates'>> => {
|
||||
const now = Date.now();
|
||||
const existing = await ctx.db
|
||||
.query('spoonRepositoryStates')
|
||||
.withIndex('by_spoon', (q) => q.eq('spoonId', args.spoonId))
|
||||
.first();
|
||||
const patch = {
|
||||
ownerId: args.ownerId,
|
||||
upstreamFullName: args.upstreamFullName,
|
||||
forkFullName: args.forkFullName,
|
||||
upstreamDefaultBranch: args.upstreamDefaultBranch,
|
||||
forkDefaultBranch: args.forkDefaultBranch,
|
||||
upstreamHeadSha: args.upstreamHeadSha,
|
||||
forkHeadSha: args.forkHeadSha,
|
||||
mergeBaseSha: args.mergeBaseSha,
|
||||
upstreamAheadBy: args.upstreamAheadBy,
|
||||
forkAheadBy: args.forkAheadBy,
|
||||
status: args.status,
|
||||
openForkPullRequestCount: args.openForkPullRequestCount,
|
||||
openUpstreamPullRequestCount: args.openUpstreamPullRequestCount,
|
||||
lastCommitAt: args.lastCommitAt,
|
||||
rawCompareUrl: args.rawCompareUrl,
|
||||
refreshedAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
if (existing) {
|
||||
if (existing.ownerId !== args.ownerId) {
|
||||
throw new ConvexError('Repository state ownership mismatch.');
|
||||
}
|
||||
await ctx.db.patch(existing._id, patch);
|
||||
return existing._id;
|
||||
}
|
||||
return await ctx.db.insert('spoonRepositoryStates', {
|
||||
spoonId: args.spoonId,
|
||||
...patch,
|
||||
createdAt: now,
|
||||
});
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user