Back to .md Directory

Global Coding Rules

**MUST** use strict TypeScript configuration as defined in tsconfig.json:

May 2, 2026
0 downloads
0 views
ai
View source

trigger: always_on

Global Coding Rules

TypeScript Configuration

MUST use strict TypeScript configuration as defined in tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2017",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  }
}

MUST enable strict mode with no exceptions:

  • Use explicit typing for function parameters
  • No any types except in rare, documented cases
  • Use proper null checks with optional chaining
  • Enable strict property initialization checks

Code Formatting and Linting

MUST use ESLint with Next.js configuration:

{
  "scripts": {
    "lint": "eslint",
    "lint:fix": "eslint --fix"
  },
  "lint-staged": {
    "./src/**/*.{ts,js,jsx,tsx}": ["eslint --fix", "prettier --write -u"]
  }
}

MUST follow these ESLint patterns:

  • Use eslint-plugin-simple-import-sort for import ordering
  • Use eslint-plugin-unused-imports to remove unused imports
  • Follow Next.js ESLint configuration standards

Import Organization

MUST organize imports in this order:

// 1. External libraries
import React from "react";
import { NextRequest } from "next/server";

// 2. Internal absolute imports (domain, services, etc.)
import User from "@/domain/entities/User";
import Sessions from "@/services/auth/Sessions";

// 3. Relative imports
import "./Component.css";

MUST use absolute imports with @/ for all internal modules:

// Good
import db from "@/persistance/db";
import UserRepository from "@/domain/repositories/UserRepository";

// Bad
import db from "../../../persistance/db";
import UserRepository from "../../domain/repositories/UserRepository";

Package Management

MUST use Yarn as package manager (as specified in package.json):

{
  "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
}

MUST specify exact versions for critical dependencies:

{
  "dependencies": {
    "@trigger.dev/sdk": "4.0.1",
    "next": "15.5.0",
    "react": "19.1.0"
  }
}

Environment Configuration

MUST use environment variables for configuration:

# Database
DATABASE_URL=postgres://user:password@host:port/database

# Authentication
JWT_SECRET=your-very-secure-jwt-secret

# External Services
RESEND_API_KEY=re_your_resend_api_key
ELASTICSEARCH_URL=https://your-elasticsearch-cluster.com

MUST provide env.example with all required variables:

# Copy to .env.local and fill in your values
DATABASE_URL=
JWT_SECRET=
RESEND_API_KEY=
ELASTICSEARCH_URL=

Error Handling Patterns

MUST use consistent error handling across layers:

// Domain layer - Use domain-specific errors
class UserNotFoundError extends Error {
  constructor(id: string) {
    super(`User with id ${id} not found`);
    this.name = "UserNotFoundError";
  }
}

// Service layer - Transform to client errors
try {
  const user = await userRepository.findById(id);
} catch (error) {
  if (error instanceof UserNotFoundError) {
    throw new ActionClientError("USER_NOT_FOUND");
  }
  throw error;
}

// Frontend - Handle gracefully
try {
  await signIn(email, password);
} catch (error) {
  setError(error.message);
}

Async/Await Patterns

MUST use async/await over Promises for readability:

// Good
const processUser = async (id: string) => {
  const user = await userRepository.findById(id);
  const result = await processData(user);
  return result;
};

// Avoid
const processUser = (id: string) => {
  return userRepository
    .findById(id)
    .then((user) => processData(user))
    .then((result) => result);
};

Naming Conventions

MUST use consistent naming patterns:

Files and Directories:

  • PascalCase: Components, Classes, Types (UserComponent.tsx, UserRepository.ts)
  • camelCase: Functions, variables (getUserById, userService.ts)
  • kebab-case: Pages, routes (user-profile.tsx, auth-callback.ts)
  • lowercase: Configuration (middleware.ts, layout.tsx)

Code Elements:

// Interfaces and Types - PascalCase
interface UserProfile {
  id: string;
  name: string;
}

// Classes - PascalCase
class UserService {
  // Methods - camelCase
  async getUserById(id: string): Promise<User> {}
}

// Constants - SCREAMING_SNAKE_CASE
const MAX_RETRY_ATTEMPTS = 3;
const API_BASE_URL = "https://api.example.com";

// Variables and functions - camelCase
const userName = "john";
const fetchUserData = async () => {};

Performance Considerations

MUST implement performance best practices:

// Use React.memo for expensive components
const ExpensiveComponent = React.memo(({ data }) => {
  return <ComplexRendering data={data} />;
});

// Use proper dependency arrays in useEffect
useEffect(() => {
  fetchData(id);
}, [id]); // Include all dependencies

// Use Next.js Image for optimized images
import Image from "next/image";
const OptimizedImage = () => (
  <Image src="/image.jpg" alt="Description" width={500} height={300} />
);

// Implement proper loading states
const [isLoading, setIsLoading] = useState(false);

Security Practices

MUST follow security guidelines:

// Validate all inputs
const validateEmail = (email: string): boolean => {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
};

// Use secure cookie settings
const cookieOptions = {
  httpOnly: true,
  secure: process.env.NODE_ENV === "production",
  sameSite: "strict" as const,
  maxAge: 7 * 24 * 60 * 60,
};

// Sanitize user inputs
const sanitizedInput = input.trim().toLowerCase();

// Use environment variables for secrets
const JWT_SECRET = process.env.JWT_SECRET!;

Git Commit Conventions

MUST use Conventional Commits with Commitizen:

{
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  }
}

Commit message format:

type(scope): description

feat(auth): add JWT token refresh functionality
fix(database): resolve connection pool timeout issue
docs(readme): update installation instructions
style(components): format button component code
refactor(services): extract common validation logic
test(auth): add unit tests for password hashing

Git Hooks with Husky

MUST use Husky for git hooks:

{
  "scripts": {
    "prepare": "husky"
  },
  "lint-staged": {
    "./src/**/*.{ts,js,jsx,tsx}": ["eslint --fix", "prettier --write -u"]
  }
}

Documentation Standards

MUST document complex functions and classes:

/**
 * Authenticates a user with email and password
 * @param email - User's email address
 * @param password - Plain text password
 * @returns Promise resolving to authenticated user
 * @throws ActionClientError when credentials are invalid
 */
const authenticateUser = async (
  email: string,
  password: string
): Promise<User> => {
  // Implementation
};

Testing Patterns

MUST follow testing conventions (when tests are added):

// Unit tests - test individual functions
describe("PasswordManager", () => {
  it("should hash passwords securely", async () => {
    const password = "test123";
    const hash = await PasswordManager.hash(password);
    expect(hash).not.toBe(password);
  });
});

// Integration tests - test service interactions
describe("AuthService", () => {
  it("should create user and send welcome email", async () => {
    const userData = { email: "test@example.com" };
    const user = await AuthService.createUser(userData);
    expect(user.id).toBeDefined();
    // Verify email was sent
  });
});

Bundle Analysis and Optimization

MUST use Next.js built-in optimization:

{
  "scripts": {
    "build": "next build --turbopack",
    "dev": "next dev --turbopack"
  }
}

MUST implement code splitting:

// Dynamic imports for large components
const HeavyComponent = dynamic(() => import("./HeavyComponent"), {
  loading: () => <Loading />,
});

// Route-based code splitting (automatic with App Router)
// pages/dashboard/page.tsx automatically creates a chunk

Logging Standards

MUST use structured logging:

const logger = {
  info: (message: string, meta?: Record<string, any>) => {
    console.log(
      JSON.stringify({
        level: "info",
        message,
        meta,
        timestamp: new Date().toISOString(),
      })
    );
  },
  error: (message: string, error?: Error) => {
    console.error(
      JSON.stringify({
        level: "error",
        message,
        error: error?.message,
        stack: error?.stack,
        timestamp: new Date().toISOString(),
      })
    );
  },
};

Code Review Guidelines

MUST ensure code reviews check for:

  • TypeScript strict compliance
  • Proper error handling
  • Security considerations (input validation, secrets)
  • Performance implications
  • Test coverage for new features
  • Documentation for complex logic
  • Consistent naming conventions
  • Proper import organization

Related Documents