ワンクリックで
convex-crud-page
Scaffold a full CRUD page with Convex schema, queries/mutations, API proxy route, and shadcn/ui React components.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Scaffold a full CRUD page with Convex schema, queries/mutations, API proxy route, and shadcn/ui React components.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
Build a full eve agent with tools, connections, skills, channels, subagents, sandbox — systematic scaffolding with known gotchas.
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
Refactor bloated AGENTS.md, CLAUDE.md, or similar agent instruction files to follow progressive disclosure principles. Splits monolithic files into organized, linked documentation.
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
| name | convex-crud-page |
| description | Scaffold a full CRUD page with Convex schema, queries/mutations, API proxy route, and shadcn/ui React components. |
| source | auto-skill |
Create a complete CRUD feature page in a Next.js + Convex + shadcn/ui app. Follows the proxy pattern: Client → API route → Convex HTTP endpoint.
convex/
schema.ts — add table definition
<entity>.ts — queries + mutations
src/app/api/<entity>/route.ts — API proxy
src/components/<entity>/ — React UI components
src/app/<entity>/page.tsx — page route
Add a table to convex/schema.ts:
<entity>: defineTable({
field1: v.string(),
field2: v.number(),
// ...
createdAt: v.number(),
updatedAt: v.number(),
}).index("by_createdAt", ["createdAt"])
Use v.id("otherTable") for foreign keys, v.optional() for nullable fields.
Create convex/<entity>.ts:
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";
// Queries (read, no side effects)
export const list = query({ args: {}, handler: async (ctx) => { ... } });
export const get = query({ args: { id: v.id("<entity>") }, handler: async (ctx, args) => { ... } });
export const search = query({ args: { query: v.string() }, handler: async (ctx, args) => { ... } });
// Mutations (write)
export const save = mutation({ args: { ... }, handler: async (ctx, args) => { ... } });
export const remove = mutation({ args: { id: v.id("<entity>") }, handler: async (ctx, args) => { ... } });
Key: The function name (e.g., list) maps to the Convex HTTP endpoint path (/api/list). The full path used in the proxy is /api/<entity>FunctionName.
Create src/app/api/<entity>/route.ts:
import { NextRequest, NextResponse } from "next/server";
import { CONVEX_URL } from "@/lib/agent/lib/env";
const ACTION_ENDPOINTS = {
list: "/api/list",
get: "/api/get",
search: "/api/search",
save: "/api/save",
remove: "/api/delete",
} as const;
type Action = keyof typeof ACTION_ENDPOINTS;
export async function POST(request: NextRequest) {
try {
const { action, args } = await request.json();
if (!CONVEX_URL) return NextResponse.json({ error: "CONVEX_URL not configured" }, { status: 500 });
if (!(action in ACTION_ENDPOINTS)) return NextResponse.json({ error: "Unsupported action" }, { status: 400 });
const res = await fetch(new URL(ACTION_ENDPOINTS[action as Action], CONVEX_URL), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(args),
});
if (!res.ok) return NextResponse.json({ error: `Convex error: ${await res.text()}` }, { status: res.status });
return NextResponse.json(await res.json());
} catch (error) {
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
}
}
Naming: The action keys in ACTION_ENDPOINTS must match the query/mutation function names in convex/<entity>.ts. The endpoint URL format is {CONVEX_URL}/api/<functionName>.
Create src/components/<entity>/. Common patterns:
<entity>-list.tsx)useEffect(() => { fetch("/api/<entity>", { method: "POST", body: JSON.stringify({ action: "list", args: {} }) }) }, [])animate-pulse<entity>-card.tsx)lucide-react)<entity>-uploader.tsx)onDragEnter/onDragLeave/onDrop<input type="file">Use Tailwind classes from the dark theme:
rounded-xl border border-glass-border bg-glasshover:border-neutral-700 transition-allbg-accent-teal text-black hover:bg-accent-teal-dimborder border-glass-bordertext-white, text-neutral-300, text-neutral-400, text-neutral-500hover:text-aurora-redCreate src/app/<entity>/page.tsx:
"use client";
export default function EntityPage() {
// State: items[], loading, showUpload
// fetchItems() via /api/<entity> POST
// handleCreate/Update/Delete wrappers
// return full-page layout with header + content
}
Include a back button (Link href="/" with ArrowLeft icon) in the header.
Add a link to the new page from the main page:
<Link href="/<entity>" className="..." aria-label="<Entity>">
<Icon className="size-4" />
</Link>
CONVEX_URL must be set — the proxy returns 500 if missing. Set NEXT_PUBLIC_CONVEX_URL in env.ACTION_ENDPOINTS must be the exact Convex function name (e.g., listFiles not list if that's what's in convex/files.ts).npx tsc won't work on Android ARM64. Validate by running bun typecheck on a real machine.