ワンクリックで
Convex database schema, mutations, queries, actions, and scheduler patterns
npx skills add https://github.com/seanchiuai/trace --skill convex-backendこのコマンドをClaude Codeにコピー&ペーストしてスキルをインストール
Convex database schema, mutations, queries, actions, and scheduler patterns
npx skills add https://github.com/seanchiuai/trace --skill convex-backendこのコマンドをClaude Codeにコピー&ペーストしてスキルをインストール
React component architecture, dark theme design system, and animation patterns
Claude Opus agentic loop — think, pick tool, execute, repeat
Browser Use Cloud API integration for autonomous web browsing
OSINT tool integrations for intelligence gathering
Convex real-time subscriptions powering live investigation updates
| name | convex-backend |
| description | Convex database schema, mutations, queries, actions, and scheduler patterns |
Convex is the sole backend — no Express, no custom server. All state, business logic, and external API calls run through Convex functions. The frontend connects via real-time subscriptions.
Four tables in convex/schema.ts:
| Table | Purpose | Key Fields |
|---|---|---|
investigations | Root record for each investigation | query, targetName, targetDescription, targetPhone, targetPhoto, knownLinks, extremeMode, status, stepCount, browserSessionId, browserLiveUrl, report, confidence, errorMessage, totalInputTokens, totalOutputTokens, estimatedCost, behavioralAnalysis, createdAt, completedAt |
findings | Individual evidence items discovered | investigationId (FK), source, category, platform, profileUrl, imageUrl, data, confidence, latitude, longitude, createdAt |
steps | Activity log for real-time frontend stream | investigationId (FK), stepNumber, action, tool, result, screenshot, createdAt |
graph_edges | Relationship connections between entities | investigationId (FK), sourceLabel, sourceType, targetLabel, targetType, relationship, createdAt |
planning → investigating → analyzing → complete
→ failed
findings.by_investigation → ["investigationId"]steps.by_investigation → ["investigationId"]graph_edges.by_investigation → ["investigationId"]| Type | Use For | File Access | Can Call APIs |
|---|---|---|---|
query | Reading data, frontend subscriptions | Read-only DB | No |
mutation | Writing data, state changes | Read/write DB | No |
action | External API calls, orchestration | Via runQuery/runMutation | Yes |
internalAction | Tool implementations (not exposed to client) | Via runQuery/runMutation | Yes |
action, mutation, query): Callable from frontend via api.*internalAction, internalMutation): Only callable from other Convex functions via internal.*Most tool implementations (convex/tools/*.ts) use internalAction — they're only called by the orchestrator, never directly from the frontend.
// convex/investigations.ts — create mutation
const id = await ctx.db.insert("investigations", {
query: `Investigate ${args.targetName}`,
targetName: args.targetName,
targetDescription: args.targetDescription,
targetPhone: args.targetPhone,
targetPhoto: args.targetPhoto,
knownLinks: args.knownLinks,
extremeMode: args.extremeMode ?? false,
status: "planning",
stepCount: 0,
createdAt: Date.now(),
});
// Always use .withIndex() for FK lookups
const findings = await ctx.db
.query("findings")
.withIndex("by_investigation", (q) =>
q.eq("investigationId", args.investigationId)
)
.order("desc")
.collect();
// convex/orchestrator.ts — chains via scheduler
await ctx.scheduler.runAfter(0, internal.orchestrator.step, {
investigationId: args.investigationId,
conversationHistory: JSON.stringify(finalHistory),
consecutiveSaveOnlySteps: consecutiveSaveOnly,
maigretAvailable,
extremeMode,
});
This avoids the 10-minute Convex action timeout by splitting each step into its own action invocation.
// Inside an action handler
await ctx.runMutation(api.investigations.updateStatus, {
id: args.investigationId,
status: "investigating",
});
// Generate upload URL for photos
export const generateUploadUrl = mutation({
handler: async (ctx) => {
return await ctx.storage.generateUploadUrl();
},
});
| File | Exports | Purpose |
|---|---|---|
convex/schema.ts | default schema | Table definitions + indexes |
convex/investigations.ts | create, get, list, updateStatus, updateReport, updateBrowserSession, incrementStep, getFindings, getSteps, addStep, addSteps, addFinding, updateTokenUsage, updateBehavioralAnalysis, generateUploadUrl | All investigation CRUD |
convex/orchestrator.ts | startInvestigation (action), step (internalAction) | Opus agentic loop |
convex/reports.ts | getReport | Assembles investigation + findings + steps |
convex/graphEdges.ts | addEdge, addEdges, getEdges | Relationship graph CRUD |
convex/tools/braveSearch.ts | search (internalAction) | Brave Search API |
convex/tools/browserUse.ts | runTask, getSession, stopSession (internalActions) | Browser Use Cloud v3 |
convex/tools/maigret.ts | search, investigate, healthCheck (internalActions) | Username OSINT via sidecar |
convex/tools/picarta.ts | localize (internalAction) | Picarta AI geolocation |
convex/tools/intelx.ts | search (internalAction) | Intelligence X dark web search |
convex/tools/reverseImageSearch.ts | search (internalAction) | Google Lens via SerpAPI |
Set in Convex dashboard (Settings → Environment Variables), NOT in .env:
ANTHROPIC_API_KEY — Claude API for orchestratorBROWSER_USE_API_KEY — Browser Use CloudBRAVE_API_KEY — Brave Search API (fast web lookups)PICARTA_API_KEY — Picarta AI geolocationINTELX_API_KEY — Intelligence X dark web search (extreme mode)SERPAPI_API_KEY — SerpAPI for reverse image searchMAIGRET_SIDECAR_URL — Maigret sidecar URL (optional, defaults to http://localhost:8000)fetch in mutations/queries — Only actions can make HTTP requestsscheduler.runAfter(0, ...) to chain long-running workflowsv.id("tableName"), not v.string() for foreign keys.query() builder with .withIndex(), .filter(), .order()addSteps and addEdges accept arrays and insert in a loop with shared timestamp, reducing round trips