History

Use typed Convex ID validators across workspace APIs

Rhys Sullivan committed 8 months ago

Commit a11d7b61 parent 96afda918 files · +111 −89Browse files

Unified · Split

18 files
  1. executor/packages/database/convex/accountsInternal.ts +3 −2
  2. executor/packages/database/convex/billing.ts +3 −2
  3. executor/packages/database/convex/billingInternal.ts +5 −4
  4. executor/packages/database/convex/billingSync.ts +2 −1
  5. executor/packages/database/convex/database/approvals.ts +4 −3
  6. executor/packages/database/convex/database/tasks.ts +5 −4
  7. executor/packages/database/convex/database/tool_calls.ts +2 −1
  8. executor/packages/database/convex/executor.ts +6 −5
  9. executor/packages/database/convex/executorNode.ts +19 −18
  10. executor/packages/database/convex/invites.ts +9 −8
  11. executor/packages/database/convex/organizationMembers.ts +4 −3
  12. executor/packages/database/convex/organizations.ts +3 −2
  13. executor/packages/database/convex/runtimeCallbacks.ts +2 −1
  14. executor/packages/database/convex/toolRegistry.ts +21 −20
  15. executor/packages/database/convex/typedV.ts +4 −0
  16. executor/packages/database/convex/workspace.ts +10 −8
  17. executor/packages/database/convex/workspaceAuthInternal.ts +6 −5
  18. executor/packages/database/convex/workspaces.ts +3 −2
executor/packages/database/convex/accountsInternal.ts+3−2
@@ -3,6 +3,7 @@ import { internal } from "./_generated/api"; · 2 unmodified lines
33 import { internalAction, internalMutation } from "./_generated/server";
44 import { deleteCurrentAccountBatchStep } from "../src/accounts/delete-current-account-batch";
55 import { safeRunAfter } from "../src/lib/scheduler";
6+import { vv } from "./typedV";
67
78 const DEFAULT_DELETE_BATCH_SIZE = 200;
89
@@ -16,7 +17,7 @@ function normalizeBatchSize(value: number | undefined): number { · 7 unmodified lines
1617
1718 export const processDeleteCurrentAccountBatch = internalMutation({
1819 args: {
19− accountId: v.id("accounts"),
20+ accountId: vv.id("accounts"),
2021 batchSize: v.optional(v.number()),
2122 },
2223 handler: async (ctx, args) => {
@@ -38,7 +39,7 @@ export const processDeleteCurrentAccountBatch = internalMutation({ · 15 unmodified lines
3839
3940 export const runDeleteCurrentAccount = internalAction({
4041 args: {
41− accountId: v.id("accounts"),
42+ accountId: vv.id("accounts"),
4243 batchSize: v.optional(v.number()),
4344 },
4445 handler: async (ctx, args) => {
executor/packages/database/convex/billing.ts+3−2
@@ -1,6 +1,7 @@
11 import { StripeSubscriptions } from "@convex-dev/stripe";
22 import { v } from "convex/values";
33 import { components, internal } from "./_generated/api";
4+import { vv } from "./typedV";
45 import { customAction, organizationMutation, organizationQuery } from "../../core/src/function-builders";
56 import {
67 createCustomerPortalHandler,
@@ -22,7 +23,7 @@ export const getSummary = organizationQuery({ · 15 unmodified lines
2223 export const createSubscriptionCheckout = customAction({
2324 method: "POST",
2425 args: {
25− organizationId: v.id("organizations"),
26+ organizationId: vv.id("organizations"),
2627 priceId: v.string(),
2728 successUrl: v.optional(v.string()),
2829 cancelUrl: v.optional(v.string()),
@@ -36,7 +37,7 @@ export const createSubscriptionCheckout = customAction({ · 7 unmodified lines
3637 export const createCustomerPortal = customAction({
3738 method: "POST",
3839 args: {
39− organizationId: v.id("organizations"),
40+ organizationId: vv.id("organizations"),
4041 returnUrl: v.optional(v.string()),
4142 sessionId: v.optional(v.string()),
4243 },
executor/packages/database/convex/billingInternal.ts+5−4
@@ -8,6 +8,7 @@ import { · 7 unmodified lines
88 upsertCustomerLinkHandler,
99 upsertSeatStateHandler,
1010 } from "../src/billing/internal-handlers";
11+import { vv } from "./typedV";
1112
1213 export const getBillingAccessForRequest = internalOrganizationQuery({
1314 args: {},
@@ -18,7 +19,7 @@ export const getBillingAccessForRequest = internalOrganizationQuery({ · 4 unmodified lines
1819
1920 export const getSeatSyncSnapshot = internalQuery({
2021 args: {
21− organizationId: v.id("organizations"),
22+ organizationId: vv.id("organizations"),
2223 },
2324 handler: async (ctx, args) => {
2425 return await getSeatSyncSnapshotHandler(ctx, args);
@@ -27,7 +28,7 @@ export const getSeatSyncSnapshot = internalQuery({ · 2 unmodified lines
2728
2829 export const upsertCustomerLink = internalMutation({
2930 args: {
30− organizationId: v.id("organizations"),
31+ organizationId: vv.id("organizations"),
3132 stripeCustomerId: v.string(),
3233 },
3334 handler: async (ctx, args) => {
@@ -37,7 +38,7 @@ export const upsertCustomerLink = internalMutation({ · 3 unmodified lines
3738
3839 export const bumpSeatSyncVersion = internalMutation({
3940 args: {
40− organizationId: v.id("organizations"),
41+ organizationId: vv.id("organizations"),
4142 },
4243 handler: async (ctx, args) => {
4344 return await bumpSeatSyncVersionHandler(ctx, args);
@@ -46,7 +47,7 @@ export const bumpSeatSyncVersion = internalMutation({ · 2 unmodified lines
4647
4748 export const upsertSeatState = internalMutation({
4849 args: {
49− organizationId: v.id("organizations"),
50+ organizationId: vv.id("organizations"),
5051 desiredSeats: v.number(),
5152 lastAppliedSeats: v.union(v.number(), v.null()),
5253 syncError: v.union(v.string(), v.null()),
executor/packages/database/convex/billingSync.ts+2−1
@@ -2,12 +2,13 @@ import { StripeSubscriptions } from "@convex-dev/stripe"; · 1 unmodified line
22 import { v } from "convex/values";
33 import { components, internal } from "./_generated/api";
44 import { internalAction } from "./_generated/server";
5+import { vv } from "./typedV";
56
67 const stripeClient = new StripeSubscriptions(components.stripe, {});
78
89 export const syncSeatQuantity = internalAction({
910 args: {
10− organizationId: v.id("organizations"),
11+ organizationId: vv.id("organizations"),
1112 expectedVersion: v.number(),
1213 },
1314 handler: async (ctx, args) => {
executor/packages/database/convex/database/approvals.ts+4−3
@@ -4,6 +4,7 @@ import { mapApproval } from "../../src/database/mappers"; · 3 unmodified lines
44 import { getApprovalDoc, getTaskDoc } from "../../src/database/readers";
55 import { approvalStatusValidator, jsonObjectValidator } from "../../src/database/validators";
66 import type { TaskStatus } from "../../../core/src/types";
7+import { vv } from "../typedV";
78
89 export const createApproval = internalMutation({
910 args: {
@@ -52,7 +53,7 @@ export const getApproval = internalQuery({ · 42 unmodified lines
5253
5354 export const listApprovals = internalQuery({
5455 args: {
55− workspaceId: v.id("workspaces"),
56+ workspaceId: vv.id("workspaces"),
5657 status: v.optional(approvalStatusValidator),
5758 },
5859 handler: async (ctx, args) => {
@@ -78,7 +79,7 @@ export const listApprovals = internalQuery({ · 19 unmodified lines
7879 });
7980
8081 export const listPendingApprovals = internalQuery({
81− args: { workspaceId: v.id("workspaces") },
82+ args: { workspaceId: vv.id("workspaces") },
8283 handler: async (ctx, args) => {
8384 const docs = await ctx.db
8485 .query("approvals")
@@ -145,7 +146,7 @@ export const resolveApproval = internalMutation({ · 60 unmodified lines
145146 });
146147
147148 export const getApprovalInWorkspace = internalQuery({
148− args: { approvalId: v.string(), workspaceId: v.id("workspaces") },
149+ args: { approvalId: v.string(), workspaceId: vv.id("workspaces") },
149150 handler: async (ctx, args) => {
150151 const doc = await getApprovalDoc(ctx, args.approvalId);
151152 if (!doc || doc.workspaceId !== args.workspaceId) {
executor/packages/database/convex/database/tasks.ts+5−4
@@ -8,6 +8,7 @@ import { · 7 unmodified lines
88 storageAccessTypeValidator,
99 storageScopeTypeValidator,
1010 } from "../../src/database/validators";
11+import { vv } from "../typedV";
1112 import { DEFAULT_TASK_TIMEOUT_MS, MAX_TASK_TIMEOUT_MS } from "../../src/task/constants";
1213 import { isTerminalTaskStatus } from "../../src/task/status";
1314
@@ -62,8 +63,8 @@ export const createTask = internalMutation({ · 48 unmodified lines
6263 runtimeId: v.string(),
6364 timeoutMs: v.optional(v.number()),
6465 metadata: v.optional(jsonObjectValidator),
65− workspaceId: v.id("workspaces"),
66− accountId: v.optional(v.id("accounts")),
66+ workspaceId: vv.id("workspaces"),
67+ accountId: v.optional(vv.id("accounts")),
6768 clientId: v.optional(v.string()),
6869 },
6970 handler: async (ctx, args) => {
@@ -107,7 +108,7 @@ export const getTask = internalQuery({ · 37 unmodified lines
107108 });
108109
109110 export const listTasks = internalQuery({
110− args: { workspaceId: v.id("workspaces") },
111+ args: { workspaceId: vv.id("workspaces") },
111112 handler: async (ctx, args) => {
112113 const docs = await ctx.db
113114 .query("tasks")
@@ -132,7 +133,7 @@ export const listQueuedTaskIds = internalQuery({ · 18 unmodified lines
132133 });
133134
134135 export const getTaskInWorkspace = internalQuery({
135− args: { taskId: v.string(), workspaceId: v.id("workspaces") },
136+ args: { taskId: v.string(), workspaceId: vv.id("workspaces") },
136137 handler: async (ctx, args) => {
137138 const doc = await getTaskDoc(ctx, args.taskId);
138139 if (!doc || doc.workspaceId !== args.workspaceId) {
executor/packages/database/convex/database/tool_calls.ts+2−1
@@ -3,12 +3,13 @@ import { internalMutation, internalQuery } from "../_generated/server"; · 2 unmodified lines
33 import { mapToolCall } from "../../src/database/mappers";
44 import { getToolCallDoc } from "../../src/database/readers";
55 import { terminalToolCallStatusValidator } from "../../src/database/validators";
6+import { vv } from "../typedV";
67
78 export const upsertToolCallRequested = internalMutation({
89 args: {
910 taskId: v.string(),
1011 callId: v.string(),
11− workspaceId: v.id("workspaces"),
12+ workspaceId: vv.id("workspaces"),
1213 toolPath: v.string(),
1314 },
1415 handler: async (ctx, args) => {
executor/packages/database/convex/executor.ts+6−5
@@ -10,6 +10,7 @@ import { · 9 unmodified lines
1010 resolveApprovalInternalHandler,
1111 } from "../src/executor/handlers";
1212 import { jsonObjectValidator } from "../src/database/validators";
13+import { vv } from "./typedV";
1314
1415 export const createTask = customAction({
1516 method: "POST",
@@ -18,9 +19,9 @@ export const createTask = customAction({ · 2 unmodified lines
1819 timeoutMs: v.optional(v.number()),
1920 runtimeId: v.optional(v.string()),
2021 metadata: v.optional(jsonObjectValidator),
21− workspaceId: v.id("workspaces"),
22+ workspaceId: vv.id("workspaces"),
2223 sessionId: v.optional(v.string()),
23− accountId: v.optional(v.id("accounts")),
24+ accountId: v.optional(vv.id("accounts")),
2425 waitForResult: v.optional(v.boolean()),
2526 },
2627 handler: async (ctx, args) => {
@@ -34,8 +35,8 @@ export const createTaskInternal = internalMutation({ · 7 unmodified lines
3435 timeoutMs: v.optional(v.number()),
3536 runtimeId: v.optional(v.string()),
3637 metadata: v.optional(jsonObjectValidator),
37− workspaceId: v.id("workspaces"),
38− accountId: v.id("accounts"),
38+ workspaceId: vv.id("workspaces"),
39+ accountId: vv.id("accounts"),
3940 clientId: v.optional(v.string()),
4041 scheduleAfterCreate: v.optional(v.boolean()),
4142 },
@@ -60,7 +61,7 @@ export const resolveApproval = workspaceMutation({ · 18 unmodified lines
6061
6162 export const resolveApprovalInternal = internalMutation({
6263 args: {
63− workspaceId: v.id("workspaces"),
64+ workspaceId: vv.id("workspaces"),
6465 approvalId: v.string(),
6566 decision: v.union(v.literal("approved"), v.literal("denied")),
6667 reviewerId: v.optional(v.string()),
executor/packages/database/convex/executorNode.ts+19−18
@@ -26,6 +26,7 @@ import { previewOpenApiSourceUpgradeForContext, type OpenApiUpgradeDiffPreview } · 25 unmodified lines
2626 import { getStorageProvider, type StorageEncoding, type StorageProvider } from "../src/runtime/storage_provider";
2727 import { shouldTouchStorageOnRead } from "../src/runtime/storage_touch_policy";
2828 import { shouldRefreshStorageUsage } from "../src/runtime/storage_usage_refresh";
29+import { vv } from "./typedV";
2930
3031 function isReadOnlySql(sql: string): boolean {
3132 const trimmed = sql.trim().toLowerCase();
@@ -109,8 +110,8 @@ async function touchStorageInstance( · 77 unmodified lines
109110 export const listToolsWithWarnings = customAction({
110111 method: "POST",
111112 args: {
112− workspaceId: v.id("workspaces"),
113− accountId: v.optional(v.id("accounts")),
113+ workspaceId: vv.id("workspaces"),
114+ accountId: v.optional(vv.id("accounts")),
114115 sessionId: v.optional(v.string()),
115116 includeDetails: v.optional(v.boolean()),
116117 includeSourceMeta: v.optional(v.boolean()),
@@ -181,8 +182,8 @@ export const listToolsWithWarnings = customAction({ · 64 unmodified lines
181182
182183 export const listToolsInternal = internalAction({
183184 args: {
184− workspaceId: v.id("workspaces"),
185− accountId: v.optional(v.id("accounts")),
185+ workspaceId: vv.id("workspaces"),
186+ accountId: v.optional(vv.id("accounts")),
186187 clientId: v.optional(v.string()),
187188 },
188189 handler: async (ctx, args): Promise<ToolDescriptor[]> => {
@@ -192,8 +193,8 @@ export const listToolsInternal = internalAction({ · 3 unmodified lines
192193
193194 export const listToolsWithWarningsInternal = internalAction({
194195 args: {
195− workspaceId: v.id("workspaces"),
196− accountId: v.optional(v.id("accounts")),
196+ workspaceId: vv.id("workspaces"),
197+ accountId: v.optional(vv.id("accounts")),
197198 clientId: v.optional(v.string()),
198199 },
199200 handler: async (
@@ -215,8 +216,8 @@ export const listToolsWithWarningsInternal = internalAction({ · 15 unmodified lines
215216
216217 export const rebuildToolInventoryInternal = internalAction({
217218 args: {
218− workspaceId: v.id("workspaces"),
219− accountId: v.optional(v.id("accounts")),
219+ workspaceId: vv.id("workspaces"),
220+ accountId: v.optional(vv.id("accounts")),
220221 clientId: v.optional(v.string()),
221222 },
222223 handler: async (ctx, args): Promise<{ rebuilt: boolean }> => {
@@ -230,8 +231,8 @@ export const rebuildToolInventoryInternal = internalAction({ · 7 unmodified lines
230231 export const previewOpenApiSourceUpgrade = customAction({
231232 method: "POST",
232233 args: {
233− workspaceId: v.id("workspaces"),
234− accountId: v.optional(v.id("accounts")),
234+ workspaceId: vv.id("workspaces"),
235+ accountId: v.optional(vv.id("accounts")),
235236 sessionId: v.optional(v.string()),
236237 sourceId: v.string(),
237238 name: v.string(),
@@ -263,8 +264,8 @@ export const previewOpenApiSourceUpgrade = customAction({ · 25 unmodified lines
263264 export const storageListDirectory = customAction({
264265 method: "POST",
265266 args: {
266− workspaceId: v.id("workspaces"),
267− accountId: v.optional(v.id("accounts")),
267+ workspaceId: vv.id("workspaces"),
268+ accountId: v.optional(vv.id("accounts")),
268269 sessionId: v.optional(v.string()),
269270 instanceId: v.string(),
270271 path: v.optional(v.string()),
@@ -291,8 +292,8 @@ export const storageListDirectory = customAction({ · 20 unmodified lines
291292 export const storageReadFile = customAction({
292293 method: "POST",
293294 args: {
294− workspaceId: v.id("workspaces"),
295− accountId: v.optional(v.id("accounts")),
295+ workspaceId: vv.id("workspaces"),
296+ accountId: v.optional(vv.id("accounts")),
296297 sessionId: v.optional(v.string()),
297298 instanceId: v.string(),
298299 path: v.string(),
@@ -322,8 +323,8 @@ export const storageReadFile = customAction({ · 23 unmodified lines
322323 export const storageListKv = customAction({
323324 method: "POST",
324325 args: {
325− workspaceId: v.id("workspaces"),
326− accountId: v.optional(v.id("accounts")),
326+ workspaceId: vv.id("workspaces"),
327+ accountId: v.optional(vv.id("accounts")),
327328 sessionId: v.optional(v.string()),
328329 instanceId: v.string(),
329330 prefix: v.optional(v.string()),
@@ -353,8 +354,8 @@ export const storageListKv = customAction({ · 23 unmodified lines
353354 export const storageQuerySql = customAction({
354355 method: "POST",
355356 args: {
356− workspaceId: v.id("workspaces"),
357− accountId: v.optional(v.id("accounts")),
357+ workspaceId: vv.id("workspaces"),
358+ accountId: v.optional(vv.id("accounts")),
358359 sessionId: v.optional(v.string()),
359360 instanceId: v.string(),
360361 sql: v.string(),
executor/packages/database/convex/invites.ts+9−8
@@ -14,6 +14,7 @@ import { · 13 unmodified lines
1414 } from "../src/invites/workos";
1515 import { normalizePersonalOrganizationName } from "../src/invites/normalize";
1616 import { safeRunAfter } from "../src/lib/scheduler";
17+import { vv } from "./typedV";
1718
1819 const organizationRoleValidator = v.union(
1920 v.literal("owner"),
@@ -124,7 +125,7 @@ export const create = organizationMutation({ · 104 unmodified lines
124125
125126 export const deliverWorkosInvite = internalAction({
126127 args: {
127− inviteId: v.id("invites"),
128+ inviteId: vv.id("invites"),
128129 inviterWorkosUserId: v.string(),
129130 expiresInDays: v.optional(v.number()),
130131 roleSlug: v.optional(v.string()),
@@ -192,7 +193,7 @@ export const revoke = organizationMutation({ · 61 unmodified lines
192193 method: "POST",
193194 requireAdmin: true,
194195 args: {
195− inviteId: v.id("invites"),
196+ inviteId: vv.id("invites"),
196197 },
197198 handler: async (ctx, args) => {
198199 const invite = await ctx.db.get(args.inviteId);
@@ -222,7 +223,7 @@ export const revoke = organizationMutation({ · 23 unmodified lines
222223
223224 export const revokeWorkosInvite = internalAction({
224225 args: {
225− inviteId: v.id("invites"),
226+ inviteId: vv.id("invites"),
226227 providerInviteId: v.string(),
227228 },
228229 handler: async (ctx, args) => {
@@ -239,7 +240,7 @@ export const revokeWorkosInvite = internalAction({ · 10 unmodified lines
239240
240241 export const getInviteDeliveryContext = internalQuery({
241242 args: {
242− inviteId: v.id("invites"),
243+ inviteId: vv.id("invites"),
243244 },
244245 handler: async (ctx, args) => {
245246 const invite = await ctx.db.get(args.inviteId);
@@ -264,7 +265,7 @@ export const getInviteDeliveryContext = internalQuery({ · 18 unmodified lines
264265
265266 export const linkOrganizationToWorkos = internalMutation({
266267 args: {
267− organizationId: v.id("organizations"),
268+ organizationId: vv.id("organizations"),
268269 workosOrgId: v.string(),
269270 },
270271 handler: async (ctx, args) => {
@@ -277,7 +278,7 @@ export const linkOrganizationToWorkos = internalMutation({ · 6 unmodified lines
277278
278279 export const getInviteById = internalQuery({
279280 args: {
280− inviteId: v.id("invites"),
281+ inviteId: vv.id("invites"),
281282 },
282283 handler: async (ctx, args) => {
283284 return await ctx.db.get(args.inviteId);
@@ -286,7 +287,7 @@ export const getInviteById = internalQuery({ · 2 unmodified lines
286287
287288 export const markInviteDelivered = internalMutation({
288289 args: {
289− inviteId: v.id("invites"),
290+ inviteId: vv.id("invites"),
290291 providerInviteId: v.string(),
291292 },
292293 handler: async (ctx, args) => {
@@ -304,7 +305,7 @@ export const markInviteDelivered = internalMutation({ · 11 unmodified lines
304305
305306 export const markInviteDeliveryFailed = internalMutation({
306307 args: {
307− inviteId: v.id("invites"),
308+ inviteId: vv.id("invites"),
308309 errorMessage: v.string(),
309310 },
310311 handler: async (ctx, args) => {
executor/packages/database/convex/organizationMembers.ts+4−3
@@ -4,6 +4,7 @@ import { getOrganizationMembership } from "../../core/src/identity"; · 3 unmodified lines
44 import { organizationMutation, organizationQuery } from "../../core/src/function-builders";
55 import { upsertOrganizationMembership } from "../src/auth/memberships";
66 import { safeRunAfter } from "../src/lib/scheduler";
7+import { vv } from "./typedV";
78
89 const organizationRoleValidator = v.union(
910 v.literal("owner"),
@@ -46,7 +47,7 @@ export const list = organizationQuery({ · 36 unmodified lines
4647 export const updateRole = organizationMutation({
4748 method: "POST",
4849 args: {
49− accountId: v.id("accounts"),
50+ accountId: vv.id("accounts"),
5051 role: organizationRoleValidator,
5152 },
5253 requireAdmin: true,
@@ -84,7 +85,7 @@ export const updateRole = organizationMutation({ · 31 unmodified lines
8485 export const updateBillable = organizationMutation({
8586 method: "POST",
8687 args: {
87− accountId: v.id("accounts"),
88+ accountId: vv.id("accounts"),
8889 billable: v.boolean(),
8990 },
9091 requireBillingAdmin: true,
@@ -114,7 +115,7 @@ export const updateBillable = organizationMutation({ · 23 unmodified lines
114115 export const remove = organizationMutation({
115116 method: "POST",
116117 args: {
117− accountId: v.id("accounts"),
118+ accountId: vv.id("accounts"),
118119 },
119120 requireAdmin: true,
120121 handler: async (ctx, args) => {
executor/packages/database/convex/organizations.ts+3−2
@@ -7,6 +7,7 @@ import { · 6 unmodified lines
77 listOrganizationsMineHandler,
88 resolveWorkosOrganizationIdHandler,
99 } from "../src/organizations/handlers";
10+import { vv } from "./typedV";
1011
1112 export const create = authedMutation({
1213 method: "POST",
@@ -37,7 +38,7 @@ export const getNavigationState = optionalAccountQuery({ · 24 unmodified lines
3738 export const getOrganizationAccess = optionalAccountQuery({
3839 method: "GET",
3940 args: {
40− organizationId: v.id("organizations"),
41+ organizationId: vv.id("organizations"),
4142 },
4243 handler: async (ctx, args) => {
4344 return await getOrganizationAccessHandler(ctx, args);
@@ -47,7 +48,7 @@ export const getOrganizationAccess = optionalAccountQuery({ · 3 unmodified lines
4748 export const resolveWorkosOrganizationId = optionalAccountQuery({
4849 method: "GET",
4950 args: {
50− organizationId: v.id("organizations"),
51+ organizationId: vv.id("organizations"),
5152 },
5253 handler: async (ctx, args) => {
5354 return await resolveWorkosOrganizationIdHandler(ctx, args);
executor/packages/database/convex/runtimeCallbacks.ts+2−1
@@ -8,6 +8,7 @@ import { · 7 unmodified lines
88 handleToolCallHandler,
99 } from "../src/runtime-callbacks/handlers";
1010 import { jsonObjectValidator } from "../src/database/validators";
11+import { vv } from "./typedV";
1112
1213 export const handleToolCall = customAction({
1314 method: "POST",
@@ -55,7 +56,7 @@ export const getTaskWatchStatus = customQuery({ · 41 unmodified lines
5556 args: {
5657 internalSecret: v.string(),
5758 runId: v.string(),
58− workspaceId: v.id("workspaces"),
59+ workspaceId: vv.id("workspaces"),
5960 },
6061 handler: async (ctx, args) => {
6162 return await getTaskWatchStatusHandler(ctx, internal, args);
executor/packages/database/convex/toolRegistry.ts+21−20
@@ -1,10 +1,11 @@
11 import { v } from "convex/values";
22 import { internal } from "./_generated/api";
33 import { internalAction, internalMutation, internalQuery } from "./_generated/server";
4+import { vv } from "./typedV";
45
56 export const getState = internalQuery({
67 args: {
7− workspaceId: v.id("workspaces"),
8+ workspaceId: vv.id("workspaces"),
89 },
910 handler: async (ctx, args) => {
1011 const entry = await ctx.db
@@ -40,7 +41,7 @@ export const getState = internalQuery({ · 29 unmodified lines
4041
4142 export const beginBuild = internalMutation({
4243 args: {
43− workspaceId: v.id("workspaces"),
44+ workspaceId: vv.id("workspaces"),
4445 signature: v.string(),
4546 buildId: v.string(),
4647 },
@@ -88,7 +89,7 @@ export const beginBuild = internalMutation({ · 41 unmodified lines
8889
8990 export const putToolsBatch = internalMutation({
9091 args: {
91− workspaceId: v.id("workspaces"),
92+ workspaceId: vv.id("workspaces"),
9293 buildId: v.string(),
9394 tools: v.array(
9495 v.object({
@@ -152,7 +153,7 @@ export const putToolsBatch = internalMutation({ · 57 unmodified lines
152153
153154 export const putNamespacesBatch = internalMutation({
154155 args: {
155− workspaceId: v.id("workspaces"),
156+ workspaceId: vv.id("workspaces"),
156157 buildId: v.string(),
157158 namespaces: v.array(
158159 v.object({
@@ -179,7 +180,7 @@ export const putNamespacesBatch = internalMutation({ · 20 unmodified lines
179180
180181 export const finishBuild = internalMutation({
181182 args: {
182− workspaceId: v.id("workspaces"),
183+ workspaceId: vv.id("workspaces"),
183184 buildId: v.string(),
184185 signature: v.string(),
185186 },
@@ -235,7 +236,7 @@ export const finishBuild = internalMutation({ · 49 unmodified lines
235236
236237 export const updateBuildMetadata = internalMutation({
237238 args: {
238− workspaceId: v.id("workspaces"),
239+ workspaceId: vv.id("workspaces"),
239240 buildId: v.string(),
240241 typesStorageId: v.optional(v.id("_storage")),
241242 warnings: v.array(v.string()),
@@ -303,7 +304,7 @@ export const updateBuildMetadata = internalMutation({ · 61 unmodified lines
303304
304305 export const failBuild = internalMutation({
305306 args: {
306− workspaceId: v.id("workspaces"),
307+ workspaceId: vv.id("workspaces"),
307308 buildId: v.string(),
308309 error: v.optional(v.string()),
309310 },
@@ -335,7 +336,7 @@ const PRUNE_NAMESPACE_SCAN_PAGE_SIZE = 250; · 25 unmodified lines
335336
336337 export const scanNamespaceBuildsForPrune = internalQuery({
337338 args: {
338− workspaceId: v.id("workspaces"),
339+ workspaceId: vv.id("workspaces"),
339340 cursor: v.optional(v.string()),
340341 },
341342 handler: async (ctx, args) => {
@@ -356,7 +357,7 @@ export const scanNamespaceBuildsForPrune = internalQuery({ · 14 unmodified lines
356357
357358 export const deleteToolRegistryToolsPage = internalMutation({
358359 args: {
359− workspaceId: v.id("workspaces"),
360+ workspaceId: vv.id("workspaces"),
360361 buildId: v.string(),
361362 cursor: v.optional(v.string()),
362363 },
@@ -376,7 +377,7 @@ export const deleteToolRegistryToolsPage = internalMutation({ · 13 unmodified lines
376377
377378 export const deleteToolRegistryPayloadsPage = internalMutation({
378379 args: {
379− workspaceId: v.id("workspaces"),
380+ workspaceId: vv.id("workspaces"),
380381 buildId: v.string(),
381382 cursor: v.optional(v.string()),
382383 },
@@ -396,7 +397,7 @@ export const deleteToolRegistryPayloadsPage = internalMutation({ · 13 unmodified lines
396397
397398 export const deleteToolRegistryNamespacesPage = internalMutation({
398399 args: {
399− workspaceId: v.id("workspaces"),
400+ workspaceId: vv.id("workspaces"),
400401 buildId: v.string(),
401402 cursor: v.optional(v.string()),
402403 },
@@ -416,7 +417,7 @@ export const deleteToolRegistryNamespacesPage = internalMutation({ · 13 unmodified lines
416417
417418 export const pruneBuilds = internalAction({
418419 args: {
419− workspaceId: v.id("workspaces"),
420+ workspaceId: vv.id("workspaces"),
420421 maxRetainedBuilds: v.optional(v.number()),
421422 },
422423 handler: async (ctx, args) => {
@@ -528,7 +529,7 @@ export const pruneBuilds = internalAction({ · 105 unmodified lines
528529
529530 export const getToolByPath = internalQuery({
530531 args: {
531− workspaceId: v.id("workspaces"),
532+ workspaceId: vv.id("workspaces"),
532533 buildId: v.string(),
533534 path: v.string(),
534535 },
@@ -569,7 +570,7 @@ export const getToolByPath = internalQuery({ · 34 unmodified lines
569570
570571 export const getSerializedToolsByPaths = internalQuery({
571572 args: {
572− workspaceId: v.id("workspaces"),
573+ workspaceId: vv.id("workspaces"),
573574 buildId: v.string(),
574575 paths: v.array(v.string()),
575576 },
@@ -601,7 +602,7 @@ export const getSerializedToolsByPaths = internalQuery({ · 25 unmodified lines
601602
602603 export const listToolsByNamespace = internalQuery({
603604 args: {
604− workspaceId: v.id("workspaces"),
605+ workspaceId: vv.id("workspaces"),
605606 buildId: v.string(),
606607 namespace: v.string(),
607608 limit: v.number(),
@@ -636,7 +637,7 @@ export const listToolsByNamespace = internalQuery({ · 28 unmodified lines
636637
637638 export const listToolsPage = internalQuery({
638639 args: {
639− workspaceId: v.id("workspaces"),
640+ workspaceId: vv.id("workspaces"),
640641 buildId: v.string(),
641642 cursor: v.optional(v.string()),
642643 limit: v.number(),
@@ -674,7 +675,7 @@ export const listToolsPage = internalQuery({ · 31 unmodified lines
674675
675676 export const listToolsBySourcePage = internalQuery({
676677 args: {
677− workspaceId: v.id("workspaces"),
678+ workspaceId: vv.id("workspaces"),
678679 buildId: v.string(),
679680 source: v.string(),
680681 cursor: v.optional(v.string()),
@@ -737,7 +738,7 @@ export const listToolsBySourcePage = internalQuery({ · 56 unmodified lines
737738
738739 export const getToolsByNormalizedPath = internalQuery({
739740 args: {
740− workspaceId: v.id("workspaces"),
741+ workspaceId: vv.id("workspaces"),
741742 buildId: v.string(),
742743 normalizedPath: v.string(),
743744 limit: v.number(),
@@ -781,7 +782,7 @@ export const getToolsByNormalizedPath = internalQuery({ · 37 unmodified lines
781782
782783 export const searchTools = internalQuery({
783784 args: {
784− workspaceId: v.id("workspaces"),
785+ workspaceId: vv.id("workspaces"),
785786 buildId: v.string(),
786787 query: v.string(),
787788 limit: v.number(),
@@ -818,7 +819,7 @@ export const searchTools = internalQuery({ · 30 unmodified lines
818819
819820 export const listNamespaces = internalQuery({
820821 args: {
821− workspaceId: v.id("workspaces"),
822+ workspaceId: vv.id("workspaces"),
822823 buildId: v.string(),
823824 limit: v.number(),
824825 },
executor/packages/database/convex/typedV.ts+4−0
@@ -0,0 +1,4 @@
1+import { typedV } from "convex-helpers/validators";
2+import schema from "./schema";
3+
4+export const vv = typedV(schema);
executor/packages/database/convex/workspace.ts+10−8
@@ -3,6 +3,7 @@ import { internal } from "./_generated/api"; · 2 unmodified lines
33 import { customMutation, workspaceMutation, workspaceQuery } from "../../core/src/function-builders";
44 import { getOrganizationMembership, isAdminRole } from "../../core/src/identity";
55 import {
6+ argumentConditionValidator,
67 credentialProviderValidator,
78 credentialScopeTypeValidator,
89 jsonObjectValidator,
@@ -17,6 +18,7 @@ import { · 8 unmodified lines
1718 toolSourceScopeTypeValidator,
1819 toolSourceTypeValidator,
1920 } from "../src/database/validators";
21+import { vv } from "./typedV";
2022 import { safeRunAfter } from "../src/lib/scheduler";
2123 import {
2224 getWorkspaceInventoryProgressForContext,
@@ -111,6 +113,8 @@ export const listTasks = workspaceQuery({ · 88 unmodified lines
111113 method: "GET",
112114 args: {},
113115 handler: async (ctx) => {
116+ // TODO(security): Revisit member-level visibility for task code/output
117+ // and provide redacted views by default outside admin contexts.
114118 return await ctx.runQuery(internal.database.listTasks, {
115119 workspaceId: ctx.workspaceId,
116120 });
@@ -121,6 +125,8 @@ export const listPendingApprovals = workspaceQuery({ · 4 unmodified lines
121125 method: "GET",
122126 args: {},
123127 handler: async (ctx) => {
128+ // TODO(security): Revisit member-level visibility for approval inputs,
129+ // which can include sensitive request payloads.
124130 return await ctx.runQuery(internal.database.listPendingApprovals, {
125131 workspaceId: ctx.workspaceId,
126132 });
@@ -192,11 +198,7 @@ export const upsertToolPolicyRule = workspaceMutation({ · 65 unmodified lines
192198 matchType: v.optional(policyMatchTypeValidator),
193199 effect: v.optional(policyEffectValidator),
194200 approvalMode: v.optional(policyApprovalModeValidator),
195− argumentConditions: v.optional(v.array(v.object({
196− key: v.string(),
197− operator: v.union(v.literal("equals"), v.literal("contains"), v.literal("starts_with"), v.literal("not_equals")),
198− value: v.string(),
199− }))),
201+ argumentConditions: v.optional(v.array(argumentConditionValidator)),
200202 priority: v.optional(v.number()),
201203 },
202204 handler: async (ctx, args) => {
@@ -244,7 +246,7 @@ export const upsertToolPolicyAssignment = workspaceMutation({ · 41 unmodified lines
244246 id: v.optional(v.string()),
245247 roleId: v.string(),
246248 scopeType: v.optional(policyScopeTypeValidator),
247− targetAccountId: v.optional(v.id("accounts")),
249+ targetAccountId: v.optional(vv.id("accounts")),
248250 clientId: v.optional(v.string()),
249251 status: v.optional(toolRoleBindingStatusValidator),
250252 expiresAt: v.optional(v.number()),
@@ -292,7 +294,7 @@ export const upsertCredential = workspaceMutation({ · 41 unmodified lines
292294 id: v.optional(v.string()),
293295 scopeType: v.optional(credentialScopeTypeValidator),
294296 sourceKey: v.string(),
295− accountId: v.optional(v.id("accounts")),
297+ accountId: v.optional(vv.id("accounts")),
296298 provider: v.optional(credentialProviderValidator),
297299 secretJson: jsonObjectValidator,
298300 overridesJson: v.optional(jsonObjectValidator),
@@ -342,7 +344,7 @@ export const resolveCredential = workspaceQuery({ · 43 unmodified lines
342344 args: {
343345 sourceKey: v.string(),
344346 scopeType: credentialScopeTypeValidator,
345− accountId: v.optional(v.id("accounts")),
347+ accountId: v.optional(vv.id("accounts")),
346348 },
347349 handler: async (ctx, args) => {
348350 return await ctx.runQuery(internal.database.resolveCredential, {
executor/packages/database/convex/workspaceAuthInternal.ts+6−5
@@ -6,10 +6,11 @@ import { · 5 unmodified lines
66 resolveWorkosAccountBySubject,
77 } from "../../core/src/identity";
88 import type { Id } from "./_generated/dataModel.d.ts";
9+import { vv } from "./typedV";
910
1011 export const getWorkspaceAccessForRequest = internalQuery({
1112 args: {
12− workspaceId: v.id("workspaces"),
13+ workspaceId: vv.id("workspaces"),
1314 sessionId: v.optional(v.string()),
1415 },
1516 handler: async (ctx, args) => {
@@ -32,7 +33,7 @@ export const getWorkspaceAccessForRequest = internalQuery({ · 16 unmodified lines
3233
3334 export const getWorkspaceAccessForWorkosSubject = internalQuery({
3435 args: {
35− workspaceId: v.id("workspaces"),
36+ workspaceId: vv.id("workspaces"),
3637 subject: v.string(),
3738 },
3839 handler: async (ctx, args) => {
@@ -55,7 +56,7 @@ export const getWorkspaceAccessForWorkosSubject = internalQuery({ · 16 unmodified lines
5556
5657 export const getWorkspaceAccessForAnonymousSubject = internalQuery({
5758 args: {
58− workspaceId: v.id("workspaces"),
59+ workspaceId: vv.id("workspaces"),
5960 accountId: v.string(),
6061 },
6162 handler: async (ctx, args) => {
@@ -83,8 +84,8 @@ export const getWorkspaceAccessForAnonymousSubject = internalQuery({ · 21 unmodified lines
8384
8485 export const getWorkspaceAccessForAccount = internalQuery({
8586 args: {
86− workspaceId: v.id("workspaces"),
87− accountId: v.id("accounts"),
87+ workspaceId: vv.id("workspaces"),
88+ accountId: vv.id("accounts"),
8889 },
8990 handler: async (ctx, args) => {
9091 const account = await ctx.db.get(args.accountId);
executor/packages/database/convex/workspaces.ts+3−2
@@ -5,12 +5,13 @@ import { · 4 unmodified lines
55 generateWorkspaceIconUploadUrlHandler,
66 listWorkspacesHandler,
77 } from "../src/workspaces/handlers";
8+import { vv } from "./typedV";
89
910 export const create = authedMutation({
1011 method: "POST",
1112 args: {
1213 name: v.string(),
13− organizationId: v.optional(v.id("organizations")),
14+ organizationId: v.optional(vv.id("organizations")),
1415 iconStorageId: v.optional(v.id("_storage")),
1516 },
1617 handler: async (ctx, args) => {
@@ -21,7 +22,7 @@ export const create = authedMutation({ · 4 unmodified lines
2122 export const list = optionalAccountQuery({
2223 method: "GET",
2324 args: {
24− organizationId: v.optional(v.id("organizations")),
25+ organizationId: v.optional(vv.id("organizations")),
2526 },
2627 handler: async (ctx, args) => {
2728 return await listWorkspacesHandler(ctx, args);