fluid-calendar / rules
Cursor rule996 starsChanged 4 months agoMITView on GitHub
send this with every request so the AI knows what to do
- Reads credentials
We split this main-rule.mdc into the rules it gives an agent
63 rules. About 0 are common, 36 are distinctive, and 27 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈36
Distinctive · estimate
This author's own choices. Worth a look.
27
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 13
when adding an external calendar like google or outlook, we still need to sync the data in our database so we are always working with our …
- Very specific: line 15
use shadcn whenever possible, the correct command to use is npx shadcn@latest add
- Distinctive: line 17
no need to touch files after making changes
- Very specific: line 18
don't use .gitignore to ignore saas-only source files, since the code is synced between the projects, instead update the sync-repos.sh …
- Distinctive: line 19
if there are changes to the rules or setup, update the main-rule.mdc file accordingly
- Distinctive: line 20
if you add methods or code that need implementation add a //todo comment explaining what it needs to do so we can implement it later
- Distinctive: line 21
when generating react content make sure to replace quotes and apostrohpes with &apos.
- Distinctive: line 23
when adding new features, consider if they should be in the saas version or the open source version or both and if you are not sure, ask to …
- Very specific: line 24
when adding new features, consider if they should be in the cmdk commands, if so ask me to confirm then add them to src/lib/commands or …
- Distinctive: line 25
use bullmq for backgound jobs and queue management.
- Very specific: line 35
All SAAS-specific code is in the src/saas/ directory, which is excluded from the open source repository via .gitignore
- Very specific: line 38
all pages for saas are in the src/app/(saas) folder and all common pages are in the src/app/(common) folder and open source in …
- Very specific: line 47
Use the isSaasEnabled and isFeatureEnabled() functions from src/lib/config.ts to conditionally enable SAAS features
- Very specific: line 51
Use route groups to organize pages: (saas), (open), and (common)
- Very specific: line 52
Place SAAS-specific pages in src/app/(saas)/ and open source pages in src/app/(open)/
- Very specific: line 55
Create separate files with .saas.tsx and .open.tsx extensions in the same directory
- Distinctive: line 56
Use dynamic imports with template literals to select the correct file based on the environment variable
- Very specific: line 63
Use the useAdmin hook to check if the user is an admin
- Very specific: line 73
Use the AdminOnly wrapper component from @/components/auth/AdminOnly
- Very specific: line 95
Use the requireAdmin middleware from @/lib/auth/api-auth
- Very specific: line 108
Do NOT use getServerSession and check the role manually
- Very specific: line 112
Use the scripts/sync-repos.sh script to sync changes from the private SAAS repository to the public open source repository
- Distinctive: line 115
When implementing new features, consider whether they should be:
- Very specific: line 125
Place reusable hooks in src/hooks
- Very specific: line 128
Keep page components in src/app
- Distinctive: line 147
Use Zustand for global state
- Very specific: line 148
Keep state logic in src/store directory
- Distinctive: line 149
Follow atomic state pattern (small, focused stores)
- Distinctive: line 150
Use local state for component-specific data
- Distinctive: line 153
Use Tailwind CSS for styling
- Very specific: line 155
Keep custom CSS in globals.css minimal
- Distinctive: line 156
Use CSS variables for theming
- Distinctive: line 160
Always define proper interfaces and types
- Distinctive: line 161
Use strict type checking
- Distinctive: line 163
Keep types in separate files when reused
- Distinctive: line 164
Use generics when appropriate
- Distinctive: line 192
Use React.memo for expensive renders
- Distinctive: line 195
Use code splitting where appropriate
- Distinctive: line 199
Use consistent error messages
- Distinctive: line 204
Never commit sensitive data
- Very specific: line 205
Use .env.example for reference
- Distinctive: line 207
Use proper naming convention
- Distinctive: line 215
Use postgres with Prisma for data persistence
- Very specific: line 216
Keep database file in /prisma directory
- Distinctive: line 217
Follow schema-first development approach
- Distinctive: line 218
Use migrations for database changes
- Distinctive: line 223
Use meaningful table names
- Distinctive: line 224
Follow consistent naming conventions
- Distinctive: line 226
Use appropriate field types
- Distinctive: line 231
Use Prisma Client for all database operations
- Very specific: line 233
Keep database logic in /src/lib/db directory
- Distinctive: line 234
Use transactions where appropriate
- Very specific: line 238
ALWAYS use the global Prisma instance from @/lib/prisma
- Very specific: line 239
NEVER create new PrismaClient instances with new PrismaClient()
- Very specific: line 240
Import Prisma types from @prisma/client but client instance from @/lib/prisma
- Distinctive: line 256
When creating a route, use this method:
- Distinctive: line 266
when you create a method, add documentation to explain what it does and update it if is changed.
- Distinctive: line 267
do not remove //todo comments in the code.
- Distinctive: line 268
if you delete/change a method or a file, make sure to refactor any usages of it.
- Distinctive: line 270
when we are discussing a new change and i tell you to start implementing then: start by creating a list of todos in TODO.md on top once we …
- Very specific: line 272
use @date-utils.ts for all date functions including new Date instead of directly using date-fns or date-fns-tz
- Very specific: line 273
use @calendar-db.ts for all db calls related to calendars
- Very specific: line 274
all logging should use the logger class defined in /lib/logger/index.js not console.log, the logger is used by importing it and also …
≈ “Common” is an estimate: at least 1 in 5 of the 6,350 Cursor rule files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
---
description: send this with every request so the AI knows what to do
globs:
alwaysApply: true
---
send this with every request so the AI knows what to do.
- this app will be a clone of the Motion app for calendar and task management
- user can add a google,outlook or caldav calendars, by clicking add calendar, get the auth screen, authorizes the app full access to the calendar
- we will be using postgres
- this app is built with nextjs, tailwind, prisma, postgres, shadcn, zod, zustand
- it uses fullcalendar package
- when adding an external calendar like google or outlook, we still need to sync the data in our database so we are always working with our local data
- the google/outlook/caldav auth needs to handle refreshing tokens so when the token expires an hour later, we can get a new one and continue syncing.
- use shadcn whenever possible, the correct command to use is `npx shadcn@latest add`
- make minimal changes and don't change or break existing logic and only apply the changes requested.
- no need to touch files after making changes
- don't use .gitignore to ignore saas-only source files, since the code is synced between the projects, instead update the sync-repos.sh script to exclude files that should not be in the open source version
- if there are changes to the rules or setup, update the main-rule.mdc file accordingly
- if you add methods or code that need implementation add a //todo comment explaining what it needs to do so we can implement it later
- when generating react content make sure to replace quotes and apostrohpes with ' and "
- as you make changes update a CHANGELOG.md file with the changes under the [unreleased] section, so we can keep track for release notes
- when adding new features, consider if they should be in the saas version or the open source version or both and if you are not sure, ask to confirm
- when adding new features, consider if they should be in the cmdk commands, if so ask me to confirm then add them to src/lib/commands or @useCommands.ts
- use bullmq for backgound jobs and queue management. all jobs are in the saas/jobs folder
## SAAS vs Open Source
This project is available in two versions:
1. **Open Source Version**: Free, self-hosted version with core functionality
2. **SAAS Version**: Hosted service with premium features
### Code Organization:
- All SAAS-specific code is in the `src/saas/` directory, which is excluded from the open source repository via `.gitignore`
- The open source repository is at https://github.com/dotnetfactory/fluid-calendar
- The private SAAS repository contains both the open source code and the SAAS-specific code
- all pages for saas are in the `src/app/(saas)` folder and all common pages are in the `src/app/(common)` folder and open source in `src/app/(open)`
- we should still add a .saas extension and .open extension to files in (saas) and (open) folders to avoid compiling them
### File Extension Convention:
- Files with `.saas.tsx`/`.saas.ts` extension are only included in the SAAS build
- Files with `.open.tsx`/`.open.ts` extension are only included in the open source build
- Regular files (without special extensions) are included in both builds
### Feature Flags:
- Use the `isSaasEnabled` and `isFeatureEnabled()` functions from `src/lib/config.ts` to conditionally enable SAAS features
- SAAS features are controlled by the `NEXT_PUBLIC_ENABLE_SAAS_FEATURES` environment variable
### Component Loading:
- Use route groups to organize pages: `(saas)`, `(open)`, and `(common)`
- Place SAAS-specific pages in `src/app/(saas)/` and open source pages in `src/app/(open)/`
- Common pages that work in both versions go in `src/app/(common)/`
- For shared components with different implementations:
- Create separate files with `.saas.tsx` and `.open.tsx` extensions in the same directory
- Use dynamic imports with template literals to select the correct file based on the environment variable
- Example: `dynamic(() => import(./path/component${process.env.NEXT_PUBLIC_ENABLE_SAAS_FEATURES === "true" ? ".saas" : ".open"}))`
- See `src/app/(common)/settings/page.tsx` for an example of this pattern
### Admin Access Control:
- Admin-only features should be secured using the `useAdmin` hook or the `AdminOnly` component
- For pages in the settings section:
- Use the `useAdmin` hook to check if the user is an admin
- Show an access denied message using the `AccessDeniedMessage` component
- Example:
```tsx
const { isAdmin } = useAdmin();
if (!isAdmin) {
return <AccessDeniedMessage message="Custom access denied message" />;
}
```
- For components:
- Use the `AdminOnly` wrapper component from `@/components/auth/AdminOnly`
- Provide a fallback component to show for non-admin users
- Example:
```tsx
<AdminOnly fallback={<AccessDeniedMessage message="Custom access denied message" />}>
{/* Admin-only content */}
</AdminOnly>
```
- For more complex access denied messages, create a custom component that uses the layout appropriate for that section
- In the settings page, use the `isSaasEnabled` constant to conditionally include admin-only tabs:
```tsx
if (isAdmin) {
const adminTabs = [/* ... */];
if (isSaasEnabled) {
return [...baseTabs, ...adminTabs, { id: "saas-feature", label: "SAAS Feature" }];
}
return [...baseTabs, ...adminTabs];
}
```
- For API routes that should only be accessible by admins:
- Use the `requireAdmin` middleware from `@/lib/auth/api-auth`
- Example:
```typescript
import { requireAdmin } from "@/lib/auth/api-auth";
export async function GET(request: NextRequest) {
// Check if user is admin
const authResponse = await requireAdmin(request);
if (authResponse) return authResponse;
// Continue with admin-only logic
}
```
- Do NOT use `getServerSession` and check the role manually
- The `requireAdmin` middleware handles all the authentication and authorization checks
### Repository Syncing:
- Use the `scripts/sync-repos.sh` script to sync changes from the private SAAS repository to the public open source repository
- The script preserves the `.gitignore` file in the public repository to prevent SAAS code from being published
When implementing new features, consider whether they should be:
1. Core features available in both versions
2. Premium features exclusive to the SAAS version
3. Core features with premium enhancements in the SAAS version
if you are not sure if this is a saas or opensource feature, then ask to confirm
# Cursor Development Rules and Guidelines
## Project Structure
- Place reusable hooks in `src/hooks`
- Store types and interfaces in `src/types`
- Maintain utilities in `src/lib`
- Keep page components in `src/app`
## Component Organization
1. Components should be organized in feature folders:
```
src/components/
calendar/
CalendarGrid.tsx
TimeSlot.tsx
WeekView.tsx
tasks/
TaskCard.tsx
TaskList.tsx
ui/
Button.tsx
Modal.tsx
```
## State Management
- Use Zustand for global state
- Keep state logic in `src/store` directory
- Follow atomic state pattern (small, focused stores)
- Use local state for component-specific data
## Styling Guidelines
- Use Tailwind CSS for styling
- Follow mobile-first approach
- Keep custom CSS in `globals.css` minimal
- Use CSS variables for theming
- Maintain consistent spacing and color schemes
## TypeScript Best Practices
- Always define proper interfaces and types
- Use strict type checking
- Avoid `any` type
- Keep types in separate files when reused
- Use generics when appropriate
## Code Organization (within files)
1. Imports order:
- React and Next.js imports
- Third-party libraries
- Local components
- Types and interfaces
- Utilities and hooks
2. Component structure:
```typescript
// Types/Interfaces
interface Props {
// ...
}
// Component
export function ComponentName({ prop1, prop2 }: Props) {
// Hooks
// State
// Effects
// Helper functions
// Render
}
```
## Performance Considerations
- Use React.memo for expensive renders
- Implement proper loading states
- Optimize images and assets
- Use code splitting where appropriate
## Error Handling
- Implement proper error boundaries
- Use consistent error messages
- Log errors appropriately
- Provide user-friendly error states
## Environment Variables
- Never commit sensitive data
- Use `.env.example` for reference
- Document required variables
- Use proper naming convention
## Common Commands
For `npm install` make sure to include the --legacy-peer-deps flag
## Database Strategy
- Use postgres with Prisma for data persistence
- Keep database file in `/prisma` directory
- Follow schema-first development approach
- Use migrations for database changes
### Database Guidelines
1. Schema Design
- Use meaningful table names
- Follow consistent naming conventions
- Include timestamps (createdAt, updatedAt)
- Use appropriate field types
- Document relationships
- Add proper indexes
2. Data Access
- Use Prisma Client for all database operations
- Implement repository pattern
- Keep database logic in `/src/lib/db` directory
- Use transactions where appropriate
- Handle errors gracefully
3. Database Connection Management
- ALWAYS use the global Prisma instance from `@/lib/prisma`
- NEVER create new PrismaClient instances with `new PrismaClient()`
- Import Prisma types from `@prisma/client` but client instance from `@/lib/prisma`
- Example:
```typescript
// ❌ Don't do this:
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// ✅ Do this instead:
import { Task, Project } from "@prisma/client"; // For types only
import { prisma } from "@/lib/prisma"; // For database access
```
# Conventions
Using Nextjs 15 with app router.
When creating a route, use this method:
```typescript
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
```
- when you create a method, add documentation to explain what it does and update it if is changed.
- do not remove //todo comments in the code.
- if you delete/change a method or a file, make sure to refactor any usages of it.
- for docker compose use `docker compose` not `docker-compose`
- when we are discussing a new change and i tell you to start implementing then: start by creating a list of todos in TODO.md on top once we agree on a plan and update the list as you implement stuff.
- for icons use react-icons
- use @date-utils.ts for all date functions including new Date instead of directly using date-fns or date-fns-tz
- use @calendar-db.ts for all db calls related to calendars
- all logging should use the logger class defined in /lib/logger/index.js not console.log, the logger is used by importing it and also defining a source:
```
import { logger } from "@/lib/logger";
const LOG_SOURCE = "OutlookCalendar";
```
here is an example for logging an error:
```
logger.error(
"Failed to refresh token",
{
error: error instanceof Error ? error.message : "Unknown error",
},
LOG_SOURCE
);
```
Where files are headingNew Cursor rule files have more rules about planning and tracking tasks, and fewer about code style.
Of the Cursor rule files we read, the 3,978 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository12 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- implement-github-issueSkill
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-exploreSkill
- openspec-proposeSkill
- review-merge-port-prSkill
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-exploreSkill
- openspec-proposeSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

