| name | standards-backend |
| description | Backend standards for modern TypeScript applications covering Convex, Supabase, Drizzle ORM, Stripe, tRPC, and API design patterns. Load when implementing server-side code, database schemas, or API endpoints. |
Backend Standards
Comprehensive backend development standards for modern TypeScript applications.
When to Use
- Setting up a new backend or database
- Implementing API endpoints
- Adding authentication or payments
- Choosing between database technologies
- Implementing real-time features
Resources
Database Selection Guide
| Use Case | Recommended Stack | Why |
|---|
| Real-time collaborative apps | Convex | Built-in subscriptions, automatic sync |
| Full-stack with auth + storage | Supabase | PostgreSQL + Auth + Storage + Realtime |
| Serverless/Edge functions | Neon + Drizzle | HTTP connections, no connection pooling |
| Traditional server apps | Prisma | Excellent DX, type safety, migrations |
| High-performance queries | Neon + Drizzle | Prepared statements, edge-optimized |
Quick Reference
Convex Schema
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
users: defineTable({
email: v.string(),
name: v.string(),
}).index("by_email", ["email"]),
});
Drizzle Schema
import { pgTable, uuid, varchar, timestamp } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: uuid("id").primaryKey().defaultRandom(),
email: varchar("email", { length: 320 }).notNull().unique(),
name: varchar("name", { length: 100 }).notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
export type User = typeof users.$inferSelect;
Supabase RLS Policy
CREATE POLICY "Users can view own data"
ON users FOR SELECT
USING (auth.uid() = id);
Stripe Webhook Handler
export async function POST(req: Request) {
const body = await req.text();
const signature = headers().get("stripe-signature")!;
const event = stripe.webhooks.constructEvent(
body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!
);
switch (event.type) {
case "checkout.session.completed":
break;
case "customer.subscription.updated":
break;
}
return new Response(null, { status: 200 });
}
tRPC Router
import { router, protectedProcedure } from "./init";
import { z } from "zod";
export const postRouter = router({
create: protectedProcedure
.input(z.object({
title: z.string().min(1),
content: z.string(),
}))
.mutation(async ({ ctx, input }) => {
return await ctx.db.insert(posts).values({
...input,
authorId: ctx.userId,
});
}),
});
Amp Tools to Use
finder - Find existing backend patterns
Read - Check API conventions
oracle - Complex architecture decisions
mcp__exa__get_code_context_exa - Research latest backend patterns
Related Skills
standards-global - TypeScript conventions
standards-frontend - Client-side data fetching
standards-testing - API testing patterns