ProgramComputer friendly-tickets .cursorrules file for TypeScript

## Key Principles

- **Code Quality & Style**
  - Write concise, maintainable, and strongly typed code with accurate TypeScript implementations.
  - Embrace functional, declarative programming. Avoid OOP and classes.
  - Limit files to a maximum of 150 lines; refactor into smaller modules if exceeded.
  - Prefer iteration and modularization over duplication.
  - Use descriptive, semantic variable names with auxiliary verbs (e.g., `isLoading`, `hasError`).
  - Use lowercase with dashes for directories and files (e.g., `components/auth-wizard`).
  - Favor named exports for components.
  - Adopt RORO (Receive an Object, Return an Object) for function parameters/returns.
  - Always attain to use DRY (Don't Repeat Yourself) principles.
  - Conduct regular code reviews and frequent refactoring sessions to ensure consistency and quality.
  - Check and improve Web Vitals (LCP, CLS, FID) to maintain performance and user experience.

- **Create 'Build Notes':**
  - You must create a 'Build Notes' file for each task group to track the progress of the task group we work on.
  - **Clarity & Brevity:** Keep notes concise, direct, and focused on the task at hand.  
  - **Logical Naming:** Use a consistent naming convention that ties each notes file to a specific task and date.  
  - **Incremental Updates:** Update notes as plans evolve or tasks are completed. Append rather than overwrite.  
  - **Traceability:** Ensure that each decision or change in approach is recorded and easy to follow.

- **Review 'Project Contexts':**
  - You must review the `projectContext.md` as we need to ensure that the project context is up to date and accurate.
  - **Stability:** Treat context files as stable references, not daily scratchpads.  
  - **Selective Updates:** Update context files only when there are significant, approved changes to requirements or project scope.  
  - **Accessibility:** Make context files easily understandable and organized so future developers can quickly grasp the project's core guidance.

- **Stack and Framework Conventions**
  - Target **Next.js 15+** and leverage the App Router, React Server Components (RSC), and SSR capabilities.
  - Use Zustand for state management in client components when necessary.
  - Maintain proper Shadcn UI management using `npx shadcn@latest add` for new components.
  - Follow a mobile-first approach and responsive design patterns.
  - Emphasize server-side logic, minimizing the usage of `use client` and other client-only APIs.
  - Structure project as Progressive Web App (PWA) with offline capabilities, app-like experience, and installability across devices.

- **Monorepo & Tooling**
  - If using a monorepo structure, place shared code in a `packages/` directory and app-specific code in `app/`.
  - Use `Taskfile.yml` commands for development, testing, and deployment tasks.
  - Keep environment variables and sensitive data outside of code and access them through `.env` files or similar configuration.

Below is a structured guideline to provide to the AI development agent, incorporating key principles and detailed rules for maintaining the `/ProjectDocs/Build_Notes/` and `/ProjectDocs/contexts/` directories.

---

### Rules for Build Notes Files

1. **Location & Naming:**  
   - Store all notes files in `/ProjectDocs/Build_Notes/`.  
   - Use a logical, descriptive naming convention, e.g., `build-title_phase-#_task-group-name.md`.
   - Use the `<build-title>` to describe the build task.
   - Use the `<phase-#>` to apply the Phase # to the build task.
   - Use the `<task-group-name>` to describe the task group name.
   - Example: `supabase-schema-standardization_phase-1_preparation-and-code-analysis.md`
       - `supabase-schema-standardization` is the build title
       - `phase-1` is the phase number
       - `preparation-and-code-analysis` is the task group name

2. **Content Structure:**  
   - Begin with a brief **Task Objective** that summarizes what you aim to achieve.  
   - Provide **Current State Assessment**: a short description of the current state of the project pertaining to the build tasks.
   - Provide **Future State Goal**: a short description of the future state of the project pertaining to the build tasks.
   - Follow with a **Implementation Plan**: a numbered list of **steps** containing checklist **tasks** to achieve the future state.
   - Update the **Implementation Plan** as tasks are completed and line out not applicable tasks. NEVER DELETE TASKS FROM THE PLAN.
   - If the plan changes or evolves, add new **steps** or **tasks**, rather than overwriting previous content.

3. **When to Update:**  
   - **At Task Start:** Create or open the task-specific notes file and record the initial plan before coding.  
   - **During Task Execution:** Add updates when plans change, difficulties arise, or new insights emerge.  
   - **At Task Completion:** Append a summary of what was done and verify it aligns with the original objective.

4. **Style & Tone:**  
   - Keep notes succinct, on-topic, and free of unrelated commentary.  
   - Maintain a logical sequence so that future readers can understand the decision-making process without confusion.

5. **Completion of Build Notes:**
   - Once the build notes are complete, move the file to the `/ProjectDocs/Build_Notes/completed/` directory.
   - If build notes are deprecated and no longer needed, move the file to the `/ProjectDocs/Build_Notes/archived/` directory.

---

### Rules for Context Files

1. **Master Project Context (`projectContext.md`):**  
   - Located in `/ProjectDocs/contexts/`.  
   - Provides the overarching project scope, requirements, and design principles.  
   - Only update this file if there are major changes to the project's fundamental direction or scope.

2. **Additional Context Files:**  
   - Supplementary files (e.g., `uiContext.md`, `featureAContext.md`) may be created for more detailed specifications on certain functionalities, designs, or areas of the application.  
   - Keep these files stable. Update them only when new, approved changes need to be documented.  
   - Reference these files frequently to ensure development aligns with established guidelines.

3. **Change Management:**  
   - Record any changes to context files within the corresponding build notes file for that task.  
   - Maintain a clear rationale for context changes to preserve transparency and alignment with the core project goals.

---

## Project Structure

Adopt a clear, modular directory structure:

```
├── app/
│   ├── (auth)/           # Auth-related routes/pages
│   ├── (dashboard)/      # Dashboard routes/pages
│   ├── api/              # API routes
│   └── layout.tsx        # Root layout
├── components/
│   ├── shared/           # Shared, reusable UI components
│   │   ├── buttons/
│   │   ├── forms/
│   │   └── layout/
│   ├── features/         # Feature-specific components
│   │   ├── auth/
│   │   └── dashboard/
│   └── ui/               # Shadcn UI components
├── lib/
│   ├── supabase/         # Supabase client and utilities
│   │   ├── current/      # Current schema and types
│   │   └── domain/       # Domain-specific schema and types
│   │       ├── user/       # User domain schema and types
│   │       │   ├── index.ts    # Exports all supabase utilities
│   │       │   ├── queries.ts  # Supabase queries
│   │       │   ├── services.ts # Supabase services
│   │       │   └── types.ts    # Supabase types
│   │       ├── roles/        # Roles domain schema and types
│   │       └── ...            # Add more domains as needed
│   ├── constants/        # Global constants and configuration
│   │   ├── auth/         # Authentication constants
│   │   └── ui/           # UI constants
│   ├── hooks/            # Custom React hooks
│   │   ├── useAuth/      # Authentication hooks
│   │   └── useUI/         # UI hooks
│   ├── middleware/       # Custom middleware
│   │   ├── auth/         # Authentication middleware
│   │   ├── rbac/         # Role-based access control middleware
│   │   └── ui/           # UI middleware
│   └── utils/            # Shared utility functions
├── public/               # Static assets
├── services/             # Business logic and data-fetching services
├── types/                # Global TypeScript types and interfaces
└── config/               # Configuration files (env, tailwind, etc.)
```

**Naming & Organization:**
- Use semantic, descriptive names.
- Keep file names lowercase with dashes.
- Use `feature/`, `bugfix/`, `hotfix/`, `refactor/`, `docs/` prefixes for branches.
- Export from `index.ts` files in feature directories for cleaner imports.

---

## JavaScript/TypeScript Standards

- Use TypeScript everywhere. Prefer `interface` for public-facing contracts.
- Use `function` keyword for defining components and pure functions (avoid arrow functions for components).
- Omit semicolons for a cleaner look.
- Maintain a logical file order:
  1. Exported component
  2. Subcomponents
  3. Helpers/internal utilities
  4. Static content/constants
  5. Types and interfaces at the bottom
- Write concise conditionals:
  - Avoid unnecessary braces in single-line conditionals.
  - Use early returns to handle edge cases and errors upfront.
- Model expected errors as return values instead of using exceptions in server actions.

Example:

```typescript
function formatInput({ input }: { input: string }) {
  if (!input) return null
  return input.trim()
}
```

---

## Error Handling, Validation, and Services

- Handle errors at the start of functions with guard clauses and early returns.
- Keep the "happy path" visible at the bottom of the function.
- Avoid `else` statements by using if-return patterns to reduce nesting.
- Use Zod for schema validation and form validation.
- Use `react-hook-form` with `useActionState` to manage form state and submission flows.
- In `services/` directories, always throw user-friendly errors that can be caught upstream and displayed to the user.
- Implement proper error logging and user-friendly messages.
- Employ error boundaries (`error.tsx`, `global-error.tsx`) for unexpected errors.
- Use `next-safe-action` for secure and type-safe server actions.

---

## AI Integration

- Use the Vercel AI SDK UI and Core to implement streaming chat and AI-driven features.
- Handle rate limiting, quota, and model availability gracefully.
- Implement fallback logic if AI models are unavailable.
- Sanitize user inputs before sending them to the AI.
- Store API keys and sensitive information in environment variables.
- Provide clear, user-friendly error messages in case of AI service failures.

---

## React/Next.js Component Development

- **Functional Components**: Use function declarations and TypeScript interfaces for props.
- **Minimal Props & Composition**: Keep components small, focused, and composed of reusable subcomponents.
- **Server Components First**: Prefer React Server Components and SSR data fetching to minimize client overhead.
- **Zustand for State**: Use Zustand for complex local state if necessary, ensuring minimal `use client` usage.
- **Client Components**: Only use `use client` for components that require browser APIs or local user interaction.
- **Responsive Design**: Use Tailwind CSS utility classes, with a mobile-first approach.
- **UI Libraries**: Use Shadcn UI and Radix UI for base components and interactions.
- **Static Content & Types**: Place static text, constants, and types at the end of each file.
- **Dynamic Loading**: Dynamically import non-critical components to improve initial load times.
- **Optimize Images**: Use WebP format, appropriate sizing, and lazy loading for images.

---

## Supabase, Database, and GraphQL

- Fetch latest Supabase documentation from https://supabase.com/docs/reference/javascript;

- **Schema Management**: Keep migrations folder under `supabase/migrations` updated with remote changes.
- **Types Management**: Keep `database.types.ts` updated regularly with the latest schema changes.
- **Migrations**: Use Supabase CLI for local development and database migrations. Test all changes before staging/production.
- **RLS & RBAC**: Implement Row Level Security and role-based access control. Assign default roles in `handle_new_user` functions.
- **CRUD-based Policies**: Follow INSERT, UPDATE, SELECT, DELETE policies and document them.
- **Enum Tables**: Use enum tables for predefined values.
- **Relationships**: Document all table relationships and data flows.
- **Genql**: Use Genql for type-safe GraphQL queries against Supabase. Fetch only necessary data.

Example user creation:

```typescript
async function handleNewUser({ userId, email }: { userId: string; email: string }) {
  const defaultRole = await getDefaultRole()
  await supabase.from('profiles').insert({
    id: userId,
    email,
    role_id: defaultRole.id,
    created_at: new Date().toISOString(),
  })
}
```
### Follow Supabase's guidelines for using the `@supabase/ssr` package and Server-Side Auth. Specifically, there should be:

- A utility function to create a client on the client side
- A utility function create a client on the server side, using the Next.js `cookies` API to access the cookies. Use the latest version of the API, where `cookies` must be awaited.
- A utility function to handle refreshing the user session in middleware.

## Working with cookies

Use the latest version of `@supabase/ssr`, where cookie options are defined with the `getAll` and `setAll` functions, like so:

```
const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
          supabaseResponse = NextResponse.next({
            request,
          })
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options)
          )
        },
      },
    }
  )
```

No other cookie options should be provided.

## Middleware

The middleware should use the following `updateSession` function:

```
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'

export async function updateSession(request: NextRequest) {
  let supabaseResponse = NextResponse.next({
    request,
  })

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
          supabaseResponse = NextResponse.next({
            request,
          })
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options)
          )
        },
      },
    }
  )

  // IMPORTANT: Avoid writing any logic between createServerClient and
  // supabase.auth.getUser(). A simple mistake could make it very hard to debug
  // issues with users being randomly logged out.

  const {
    data: { user },
  } = await supabase.auth.getUser()

  if (
    !user &&
    !request.nextUrl.pathname.startsWith('/login') &&
    !request.nextUrl.pathname.startsWith('/auth')
  ) {
    // no user, potentially respond by redirecting the user to the login page
    const url = request.nextUrl.clone()
    url.pathname = '/login'
    return NextResponse.redirect(url)
  }

  // IMPORTANT: You *must* return the supabaseResponse object as it is. If you're
  // creating a new response object with NextResponse.next() make sure to:
  // 1. Pass the request in it, like so:
  //    const myNewResponse = NextResponse.next({ request })
  // 2. Copy over the cookies, like so:
  //    myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
  // 3. Change the myNewResponse object to fit your needs, but avoid changing
  //    the cookies!
  // 4. Finally:
  //    return myNewResponse
  // If this is not done, you may be causing the browser and server to go out
  // of sync and terminate the user's session prematurely!

  return supabaseResponse
}
```
### Postgres SQL Style Guide

## General

- Use lowercase for SQL reserved words to maintain consistency and readability.
- Employ consistent, descriptive identifiers for tables, columns, and other database objects.
- Use white space and indentation to enhance the readability of your code.
- Store dates in ISO 8601 format (`yyyy-mm-ddThh:mm:ss.sssss`).
- Include comments for complex logic, using '/* ... */' for block comments and '--' for line comments.

## Naming Conventions

- Avoid SQL reserved words and ensure names are unique and under 63 characters.
- Use snake_case for tables and columns.
- Prefer plurals for table names
- Prefer singular names for columns.

## Tables

- Avoid prefixes like 'tbl_' and ensure no table name matches any of its column names.
- Always add an `id` column of type `identity generated always` unless otherwise specified.
- Create all tables in the `public` schema unless otherwise specified.
- Always add the schema to SQL queries for clarity.
- Always add a comment to describe what the table does. The comment can be up to 1024 characters.

## Columns

- Use singular names and avoid generic names like 'id'.
- For references to foreign tables, use the singular of the table name with the `_id` suffix. For example `user_id` to reference the `users` table
- Always use lowercase except in cases involving acronyms or when readability would be enhanced by an exception.

#### Examples:

```sql
create table books (
  id bigint generated always as identity primary key,
  title text not null,
  author_id bigint references authors (id)
);
comment on table books is 'A list of all the books in the library.';
```


## Queries

- When the query is shorter keep it on just a few lines. As it gets larger start adding newlines for readability
- Add spaces for readability.

Smaller queries:


```sql
select *
from employees
where end_date is null;

update employees
set end_date = '2023-12-31'
where employee_id = 1001;
```

Larger queries:

```sql
select
  first_name,
  last_name
from
  employees
where
  start_date between '2021-01-01' and '2021-12-31'
and
  status = 'employed';
```


### Joins and Subqueries

- Format joins and subqueries for clarity, aligning them with related SQL clauses.
- Prefer full table names when referencing tables. This helps for readability.

```sql
select
  employees.employee_name,
  departments.department_name
from
  employees
join
  departments on employees.department_id = departments.department_id
where
  employees.start_date > '2022-01-01';
```

## Aliases

- Use meaningful aliases that reflect the data or transformation applied, and always include the 'as' keyword for clarity.

```sql
select count(*) as total_employees
from employees
where end_date is null;
```


## Complex queries and CTEs

- If a query is extremely complex, prefer a CTE.
- Make sure the CTE is clear and linear. Prefer readability over performance.
- Add comments to each block.

```sql
with department_employees as (
  -- Get all employees and their departments
  select
    employees.department_id,
    employees.first_name,
    employees.last_name,
    departments.department_name
  from
    employees
  join
    departments on employees.department_id = departments.department_id
),
employee_counts as (
  -- Count how many employees in each department
  select
    department_name,
    count(*) as num_employees
  from
    department_employees
  group by
    department_name
)
select
  department_name,
  num_employees
from
  employee_counts
order by
  department_name;
```


---

## Version Control and Workflow

- **Branch Naming**: `feature/`, `bugfix/`, `hotfix/`, `refactor/`, `docs/`.
- **Commit Messages**: Use `type(scope): description` format. Common types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`.
- **Pull Requests**: Use PR templates with a summary, change type, testing steps, and any database changes noted.
- **Schema Updates**: Update `schema.sql` and commit the changes after each migration.
- **Testing Before PR**: Always test changes locally before submitting PRs.

---

## Data Fetching and State Management

- **RSC for Data**: Use React Server Components for data fetching whenever possible.
- **Preload Pattern**: Implement preload patterns to avoid waterfall requests.
- **Supabase for Real-Time**: Use Supabase subscriptions for real-time data and SSR-friendly data access.
- **Zustand**: Manage local state in isolated client components when needed.
- **Vercel KV**: Use Vercel KV for chat history, rate limiting, and ephemeral storage.
- **SSR & Minimize 'use client'**: Prefer SSR and server actions. Only use `use client` for browser-based interactions.

---

## Testing and Quality Assurance

- **Unit Tests**: Write unit tests for utilities, hooks, and business logic.
- **Integration Tests**: Test complex components, pages, and features in isolation.
- **End-to-End Tests**: Validate critical flows (login, checkout) end-to-end.
- **Local DB Testing**: Use Supabase local development for realistic database tests.
- **Coverage**: Maintain a minimum test coverage threshold for PR merges.

---

## Styling and Accessibility

- **Tailwind CSS**: Use utility classes with a mobile-first responsive approach.
- **CVA for Variants**: Employ Class Variance Authority for component variants and theme consistency.
- **Radix UI**: Utilize Radix primitives for accessible UI patterns.
- **ARIA & WCAG**: Ensure proper ARIA labels, roles, and adhere to WCAG guidelines for color contrast and keyboard navigation.
- **Shadcn UI**: Leverage shadcn UI components for design consistency and speed.

---

## Documentation

- **Comments & JSDoc**: Comment complex logic and use JSDoc for functions and components.
- **Readmes**: Keep README files updated with setup, instructions, and architectural details.
- **API & DB Docs**: Document all API endpoints, RLS policies, and database schema.
- **Edge Functions**: Document Supabase Edge Functions and their intended usage.
- **Setup Instructions**: Keep environment configuration and setup steps current for onboarding developers.

---

**Remember:**
- Regularly check file sizes; refactor when needed.
- Maintain separation of concerns and modular design.
- Reuse components and keep them composable and testable.
- Always test locally before pushing changes.
- Ensure proper error handling, user-friendly messages, and accessible interfaces.

## Supabase Migration Rules

- **CRITICAL: Migration File Management**
  - NEVER modify existing migration files. Each change requires a new migration file with a fresh timestamp.
  - Use `npx supabase migration new <descriptive-name>` to create new migrations.
  - Keep migration names short but descriptive (e.g., `add-user-index`, `update-ticket-constraints`).
  - One logical change per migration file - don't combine unrelated schema changes.
  - Test migrations locally before pushing to production.

- **Migration Best Practices**
  - Include `drop if exists` statements to make migrations idempotent.
  - Add comments explaining the purpose of each migration.
  - For constraint changes, include both `drop constraint if exists` and `add constraint`.
  - Order operations correctly (e.g., drop dependent objects before their dependencies).
  - Always specify the schema (e.g., `public.users` instead of just `users`).

- **Schema Management**
  - Keep `supabase/migrations/` in sync with remote changes.
  - Document schema changes in both migration files and project documentation.
  - Use `npx supabase db reset` for local development only.
  - Use `npx supabase db push` for remote database updates.
  - Never use `db reset` on production/remote databases.

- **Types and Validation**
  - Generate and commit TypeScript types after schema changes using `supabase gen types typescript`.
  - Use Zod schemas that match database constraints.
  - Keep `database.types.ts` updated with latest schema.

- **Security and Access Control**
  - Document RLS policies in both migrations and project documentation.
  - Test RLS policies with different user roles.
  - Use service role only for administrative tasks (seeding, migrations).
  - Never expose service role key in client-side code.

## Database Standards

- **Naming Conventions**
  - Use snake_case for all database objects (tables, columns, functions).
  - Prefix function names with verb (e.g., `get_user`, `update_status`).
  - Use plural for table names (e.g., `users`, `tickets`).
  - Use singular for column names and foreign keys (e.g., `user_id`).

- **Column Standards**
  - Include `created_at` and `updated_at` on all tables.
  - Use `uuid` for primary keys unless there's a specific reason not to.
  - Add appropriate indexes for foreign keys and frequently queried columns.
  - Document constraints and indexes in migration files.

- **Error Handling**
  - Use custom error codes for database functions.
  - Implement proper error handling in application code.
  - Log database errors appropriately.
  - Provide user-friendly error messages.

## Testing and Validation

- **Migration Testing**
  - Test migrations in both directions (up/down).
  - Verify data integrity after migrations.
  - Test with realistic data volumes.
  - Check performance impact of schema changes.

- **Data Seeding**
  - Keep seed data minimal but sufficient for testing.
  - Use service role for seeding operations.
  - Document seed data structure and purpose.
  - Include different test scenarios in seed data.
css
golang
graphql
java
javascript
less
nestjs
next.js
+10 more

First Time Repository

TypeScript

Languages:

CSS: 7.8KB
JavaScript: 1.4KB
PLpgSQL: 29.5KB
TypeScript: 671.8KB
Created: 1/21/2025
Updated: 1/23/2025

All Repositories (1)