StarterApp Docs
AI Workflow

Templates

Production-ready code patterns for AI-assisted development

Templates provide complete implementations for common development tasks. Located in /llms/templates/, these files contain security measures, validation, and error handling built in. AI assistants reference these patterns to generate consistent, production-ready code.

Pro Tip

Templates are complete, production-ready code patterns—not snippets. Copy and adapt them directly in your codebase. AI assistants use these same templates as reference when generating code.

Quick Reference

API Routes

Templates for building secure, type-safe API endpoints.

Server Actions

Templates for Next.js Server Actions using next-safe-action v8.

Pages and Components

Templates for authenticated pages and subscription-gated components.

Testing

Templates for integration and unit testing.

AI-Assisted Development with Templates

Templates enhance AI code generation through three mechanisms.

Template Patterns

All templates follow consistent patterns that work together to create secure, maintainable code.

Validation

All templates use Zod for runtime validation:

const BodySchema = z.object({
  title: z.string().trim().min(1).max(200),
  content: z.string().trim().min(10).max(5000),
});

// Parse and validate
const body = BodySchema.parse(await req.json());

This ensures type safety at runtime and provides clear error messages for invalid inputs.

Authentication

Protected routes and actions verify user sessions:

const session = await auth.api.getSession({ headers: await headers() });

if (!session?.user?.id) {
  throw new RouteError({
    status: 401,
    code: "Unauthorized",
    message: "Authentication required",
  });
}

Never skip authentication checks on protected resources.

Error Handling

Templates use discriminated unions for type-safe error handling:

class RouteError extends Error {
  readonly init: {
    status: number;
    code: string;
    message: string;
    userScoped?: boolean;
  };
}

function respond(error: unknown): RouteResult {
  if (error instanceof RouteError) {
    return secureErrorJson(
      {
        message: error.init.message,
        code: error.init.code,
      },
      { status: error.init.status, userScoped: error.init.userScoped }
    );
  }
  if (error instanceof z.ZodError) {
    return secureErrorJson(
      {
        message: "Validation failed",
        code: "ValidationError",
        issues: error.issues.map((issue) => issue.message),
      },
      { status: 400, userScoped: true }
    );
  }
  return secureErrorJson(
    { message: "Internal server error", code: "Internal" },
    { status: 500, userScoped: true }
  );
}

This pattern ensures errors never leak sensitive information.

Security Headers

Templates apply appropriate security headers:

// From @workspace/security
export function secureUserJson(data: unknown, options?: {
  status?: number;
  userScoped?: boolean;
}) {
  return NextResponse.json(data, {
    status: options?.status ?? 200,
    headers: {
      'Cache-Control': 'private, no-store',
      'Vary': 'Cookie',
      // Additional security headers...
    },
  });
}

User-scoped responses never cache. Error responses hide implementation details.

Type Safety

Templates use explicit types throughout:

// Schema inference
type CreateResourceInput = z.infer<typeof BodySchema>;

// Return type from helper
type RouteResult = Awaited<ReturnType<typeof secureUserJson>>;

// Discriminated unions for domain logic
type PersistResult =
  | { ok: true; data: Resource }
  | { ok: false; validationErrors: ValidationErrors };

No any types. Every value has explicit type information.

Learn how templates integrate with other AI workflow components: