Skip to content

Commit

Permalink
Update cursorrules file (#43)
Browse files Browse the repository at this point in the history
* Use expanded cursorrules after testing

* update package-lock
  • Loading branch information
wardbox authored Jan 25, 2025
1 parent 9c7a763 commit d7ed5c8
Show file tree
Hide file tree
Showing 2 changed files with 12,000 additions and 7,200 deletions.
241 changes: 228 additions & 13 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -1,26 +1,241 @@
// Wasp Import Rules
- Import Wasp functions from 'wasp' package, not '@wasp'
# Overview
You are a TypeScript, Node.js, Wasp, React, Shadcn UI, Radix UI, Zod, React Hook Form, and TailwindCSS expert with deep knowledge on each topic.
This project is a Wasp app template. It includes a bunch of examples and guides.
You are helping a developer set up the project and add new pages while using the project's conventions as an example.

# Wasp Rules
## main.wasp and general
- Wasp is on ^0.15.x
- Try not to remove things from main.wasp unless the user asks you to, if you do, use the existing code as an example.
- When you add a route, page, action, query, or job to main.wasp the app will not work
until you add the related file to the directory, so make sure to add one.

## Actions and Queries
- Store actions and queries together in feature/operations.ts
- For queries, always use the satisfies keyword so we can dynamically type the response later with
```
export interface ExampleProps {
example: Awaited<ReturnType<typeof getExample>>
}
```

## Routing
- Use Wasp's built-in Link component from wasp/client/router for internal links
- Use <a> elements for external links and anchor links

# Import Rules

## Wasp Imports
- Always import Wasp functions from 'wasp' package, not '@wasp'
✓ import { Task } from 'wasp/entities'
✓ import { type GetTasks } from 'wasp/server/operations'
✓ import { getTasks, useQuery } from 'wasp/client/operations'
✗ import { ... } from '@wasp/...'

// Wasp Schema Rules
## React Imports
- Do not import React from 'react' because it's automatically imported
- Import hooks directly from packages:
✓ import { useState } from 'react'
✗ import React, { useState } from 'react'

## Motion Imports
- Import from 'motion/react' instead of 'framer-motion'
✓ import { motion } from 'motion/react'
✗ import { motion } from 'framer-motion'

## General Imports
- Never use the @ alias, use relative imports only.
- When the user manually updates the import you suggest, please don't change it back.

# Schema & Data Models

## Prisma Schema
- Add new entities (models) to 'schema.prisma', NOT 'main.wasp'
- Use meaningful names for models and fields
- Add proper relations between models
- Include field validations where needed
- Provide default values where it makes common sense (fields like createdAt and updatedAt can default to now)
- Follow Prisma naming conventions:
✓ Model names: PascalCase (User, Task)
✓ Field names: camelCase (firstName, createdAt)

// Wasp Dependencies
# Dependencies & Package Management

## Installation
- Do NOT add dependencies to 'main.wasp'
- Install dependencies via 'npm install' instead
- Use exact versions for critical dependencies
- Keep dependencies up to date
- Keep dependencies in package.json

# TypeScript

## General
- Always use TypeScript for new files
- Enable strict mode in tsconfig
- Define proper types for all variables and functions
- Use type inference when types are obvious
- Use .tsx extension for React components
- Use .ts extension for non-React files
- Define proper types for operations:
✓ type GetTasks = QueryFn<void, Task[]>
✓ type CreateTask = ActionFn<{ description: string }, Task>

## Type Definitions
- Place shared types in the same file they will be used in.
- Use interface for object types that can be extended
- Use type for unions, intersections, and mapped types

# Styling

## Icon library
- Use @phosphor-icons/react for icons

## Tailwind CSS
- Use Tailwind CSS for styling
- Do not use inline styles unless absolutely necessary
- Follow semantic color naming:
✓ text-destructive, text-muted-foreground
✗ text-red-500, text-gray-600
- Let the theme handle colors and spacing
- Follow mobile-first approach

## Lint and format
- Follow these prettier rules
{
"arrowParens": "avoid",
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"bracketSameLine": false,
"jsxSingleQuote": true,
"printWidth": 80,
"proseWrap": "always",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"useTabs": false,
}
- Use &apos; for apostrophes in content


## Component Structure
- Group related styles together
- Use meaningful class names
- Leverage Tailwind's responsive utilities
- Use good UI spacing via the tailwind gap class.

# State Management
- Use Wasp's built-in auth state management
- Use Wasp's built-in useQuery for server state
- Use local state (useState) for UI state
- Use context sparingly and only for truly global state
- Use appropriate hooks for state management
- Keep state as local as possible
- Avoid prop drilling with context when needed
- Implement proper error boundaries

# Performance
- Use proper key props in lists
- Use precaching for routes where it makes sense
- Use proper caching strategies
- Implement proper data fetching patterns
- Use proper React Query configurations
- Use proper code splitting

// Wasp
- Always use typescript for Wasp code.
# Accessibility
- Use semantic HTML elements
- Include proper ARIA labels
- Ensure keyboard navigation works
- Maintain sufficient color contrast
- Support reduced motion preferences
- Support screen readers
- Implement proper ARIA attributes

// Framer Motion
- Use 'motion/react' instead of 'framer-motion', this is the new opensourced version of Framer Motion.
# Error Handling
- Implement proper error boundaries
- Use type-safe error handling
- Log errors appropriately
- Provide user-friendly error messages
- Handle operation errors appropriately:
✓ try { await createTask(...) } catch (e) { handleError(e) }

// CSS
- Use Tailwind CSS for styling.
- Do not use inline styles.
# Project Structure
- Organize code by features (vertically) rather than technical layers
✓ src/tasks/{actions.ts,queries.ts,TaskList.tsx}
✓ src/auth/{actions.ts,LoginPage.tsx}
✗ src/client/components/TaskList.tsx
- Keep source files in src/
- Keep static files in public/
- Use feature-based organization: ```
src/
├── tasks/
│ ├── actions.ts
│ ├── queries.ts
│ └── TaskList.tsx
├── auth/
│ ├── actions.ts
│ ├── LoginPage.tsx
│ └── RegisterPage.tsx
└── shared/
└── utils.ts ```

// General
- Use single quotes
# Forms
- Use React Hook Form for form actions like useForm and zodresolver
- Use Zod to validate form schemas
- Here is an example form using both
```
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"

import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"

const formSchema = z.object({
username: z.string().min(2, {
message: "Username must be at least 2 characters.",
}),
})

export function ProfileForm() {
// ...

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}
```
- Type validate all form inputs.
Loading

0 comments on commit d7ed5c8

Please sign in to comment.