
Never Constraints
- 3 installs
- 3 repo stars
- Updated April 4, 2026
- mohitmishra786/never
Helps with ai & agent building tasks.
About
never-constraints is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- never-constraints
- AI & Agent Building
- AI-coding skill
Never Constraints by the numbers
- 3 all-time installs (skills.sh)
- Ranked #13,657 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mohitmishra786/never --skill never-constraintsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3 |
|---|---|
| repo stars | ★ 3 |
| Last updated | April 4, 2026 |
| Repository | mohitmishra786/never ↗ |
What it does
Helps with ai & agent building tasks.
Files
Never Constraints
Comprehensive coding standards and constraints that apply to all code generation and editing tasks. Load relevant reference files based on the tech stack in use.
Core Constraints
AI Assistant Behavior
- Never suggest running
npm audit fix --force; it breaks dependencies by forcing major version upgrades - Never generate code using deprecated APIs without checking the library version first
- Never assume an API or library feature exists; verify in current documentation
- Never invent fake libraries, functions, or APIs; only use real, documented features
- Never apologize repeatedly; just correct the code immediately
- Never provide overly verbose explanations when the code is self-explanatory
- Never use phrases like "As an AI" or "I cannot" unless there's a genuine technical limitation
- Never generate placeholder code with
// TODO: Implement thisunless specifically asked - Never add console.log statements for debugging unless specifically asked
- Never generate code that requires dependencies not already in the project without asking first
- Never use
anytype in TypeScript without a strong justification - Never refactor code that wasn't requested; only fix what the user asked for
- Never change the public API of a function without explicit permission
- Never remove functionality unless explicitly instructed
- Never upgrade major versions of dependencies without warning about breaking changes
- Never generate code with hardcoded credentials, even for examples; use placeholders
- Never suggest disabling security features (CORS, CSRF, SSL validation) without strong warnings
- Never generate SQL queries with string concatenation; always use parameterized queries
- Never overwrite existing files without confirming the changes with the user first
- Never delete files without explicit confirmation
- Never suggest using
console.logas the primary debugging method; recommend proper debuggers - Never generate tests that always pass; write meaningful assertions
- Never skip error cases in tests; test both success and failure scenarios
- Never mix package managers (npm, yarn, pnpm) in the same project
- Never suggest
npm installwhen project usesyarn.lockorpnpm-lock.yaml - Never ignore lockfile conflicts; help resolve them properly
- Never assume Node.js version; check
enginesfield in package.json or ask - Never assume Python 2 is available; default to Python 3
- Never use shell commands that only work in bash when user might be on Windows (cmd/PowerShell)
- Never change existing code formatting style unless specifically asked
- Never add trailing whitespace or change line endings without reason
- Never reformat entire files when only changing one function
- Never generate JSDoc or comments that just repeat the function signature
- Never add copyright headers unless the project already has them
- Never generate README files with generic/placeholder content
Code Quality
- Never write redundant or duplicate logic; strictly follow DRY (Don't Repeat Yourself)
- Never create functions longer than 50-75 lines without strong justification
- Never nest conditionals more than 3 levels deep; refactor into separate functions
- Never use magic numbers; define constants with descriptive names
- Never hallucinate or invent fake libraries, APIs, or functions
- Never assume an API exists without verifying it in documentation
- Never leave unused imports or dead code in the final output
- Never generate "placeholder" code or // TODO comments unless specifically asked
- Never leave debugging statements (console.log, print, etc.) in production code
- Never commit commented-out code blocks
- Never edit files without explicit permission or sufficient context from the user
- Never silently change behavior that the user didn't ask to change
- Never remove existing functionality unless explicitly instructed
- Never make assumptions about what the user wants; ask if unclear
- Never use generic variable names like
data,item,obj,value,temp, or single letters (except loop counters); use descriptive names - Never use abbreviations unless they're industry-standard; spell out names (
userRepositorynotusrRepo) - Never name boolean variables without
is,has,should, orcanprefixes - Never use "magic numbers" or magic strings in business logic (
if (status == 2)); define named constants - Never hardcode configuration values like timeouts, limits, or URLs in code; extract to configuration files
- Never catch an error and silently ignore it (
catch (e) {}orexcept: pass); always log the error or handle it explicitly - Never use generic error messages like "Something went wrong"; include context
- Never throw strings or primitive values as errors; throw Error objects with stack traces
- Never swallow errors in promise chains without logging
- Never use nested ternary operators (
a ? b : c ? d : e); use if/else statements - Never create functions with more than 4-5 parameters; use parameter objects
- Never write comments that explain WHAT the code does; write comments that explain WHY
- Never write a Regular Expression without a comment explaining what it matches
- Never leave TODO comments without a ticket/issue reference
- Never import from parent directories more than two levels deep (
../../utils); use path aliases - Never create circular dependencies between modules; refactor to extract shared code
- Never mix business logic with presentation logic; separate concerns
- Never write code without accompanying tests unless it's a prototype
- Never leave console.log "breadcrumbs" in final code (
console.log("here 1")) - Never perform expensive operations (API calls, database queries) inside loops; extract and batch
- Never fetch all records from database when you only need a subset; use pagination or
LIMIT - Never use synchronous operations in async contexts; use async variants
- Never use deprecated APIs or libraries; migrate to modern alternatives
- Never install packages without checking their maintenance status
- Never modify
package-lock.json,yarn.lock, or similar lock files manually - Never ignore TypeScript errors with
@ts-ignoreoranywithout a comment explaining why - Never use
varin JavaScript; useconstby default andletwhen reassignment is needed - Never compare with
==in JavaScript; use strict equality=== - Never commit generated files (
dist/,build/) to version control; add to.gitignore - Never commit commented-out code; delete it and use version control to recover if needed
- Never make massive commits with unrelated changes; commit logical units of work
Security
- Never include plain-text secrets, API keys, or tokens in code
- Never hardcode sensitive credentials; always use environment variables or secret management systems
- Never commit .env files or any file containing real credentials to version control
- Never disable SSL/TLS verification in network requests
- Never trust user input for constructing URLs without validation
- Never expose internal system paths or server metadata in error messages
- Never use eval() or similar functions that execute arbitrary strings
- Never use dynamic code execution with unsanitized input
- Never deserialize untrusted data without validation
- Never use MD5 or SHA1 for password hashing; use bcrypt, scrypt, or Argon2
- Never implement custom cryptographic algorithms; use established libraries
- Never use ECB mode for block ciphers
- Never use predictable values for cryptographic seeds or IVs
- Never skip input sanitization for user-provided data
- Never trust client-side validation alone; always validate server-side
- Never interpolate user input directly into SQL queries, shell commands, or file paths
- Never use
Math.random()for security tokens, session IDs, or cryptographic operations; strictly usecrypto.getRandomValues()orcrypto.randomBytes() - Never store passwords in plain text or with reversible encryption; always use one-way hashing with salt
- Never use
innerHTML,dangerouslySetInnerHTML, orv-htmlwith unsanitized user input; use safe text interpolation or DOMPurify - Never expose database ports (5432, 6379, 27017) to
0.0.0.0in production; bind to127.0.0.1or use private networks - Never use
chmod 777orchmod -R 777in Dockerfiles or production systems; use minimal required permissions - Never disable SSL/TLS certificate validation in production (
rejectUnauthorized: false) - Never use HTTP for internal service-to-service communication; enforce HTTPS, mTLS, or VPN tunnels
- Never log raw HTTP headers, request bodies, or response data without redacting sensitive fields (Authorization, Cookie, password fields)
- Never log credit card numbers, SSNs, or other PII without masking
- Never expose detailed error messages with stack traces to end users in production
- Never use
npm audit fix --forcewithout reviewing changes; manually audit breaking changes - Never install packages from untrusted registries without verification
- Never ignore security warnings from dependency scanners
- Never store JWT tokens or session IDs in localStorage; use httpOnly cookies
- Never rely solely on client-side authorization checks; always validate permissions server-side
- Never use predictable session IDs or tokens; use cryptographically random UUIDs
- Never execute shell commands constructed from user input without escaping
- Never allow file uploads without validating file type by content (magic bytes), not just extension
- Never serve uploaded files from the same domain as your application; use a separate CDN or subdomain
Communication & Tone
- Never use emojis in responses, documentation, code comments, or commit messages
- Never use patronizing or shaming language (e.g., "It's simple," "Just...," "Obviously")
- Never use condescending phrases that imply the user should already know something
- Never use exclamation marks excessively; maintain a calm, professional tone
- Never provide conversational filler like "Certainly!" "I'd be happy to help!" or "Great question!"
- Never output verbose explanations unless the user explicitly asks for detailed reasoning
- Never repeat information the user already provided back to them
- Never pad responses with unnecessary context or caveats
- Never invent explanations for behavior you don't understand
- Never pretend to have capabilities you don't have
- Never claim certainty when you are unsure; express uncertainty appropriately
- Never avoid admitting mistakes; acknowledge and correct them promptly
- Never write documentation that assumes insider knowledge without explanation
- Never use jargon without defining it when writing for general audiences
- Never leave ambiguous pronouns (it, this, that) without clear referents
- Never output verbose prose like "Here is the updated code..."; provide only code blocks or brief summaries
- Never suggest "next steps" at the end of a response; let the user drive the workflow
- Never apologize for making a mistake; just fix the code immediately
- Never use hesitant language like "I believe" or "I think"; use precise statements
Code Hygiene
- Never use emojis in commit messages or code comments; maintain professional code documentation
- Never create summary.md, notes.md, or todo.txt files unless explicitly asked; these create repository clutter
- Never rewrite entire files to change a single variable name; keep diffs minimal
- Never use placeholders like
// ... rest of code; always provide the full function or file - Never use markdown bolding inside code comments; it renders poorly in IDEs
- Never delete existing comments unless they are explicitly incorrect; comments provide valuable context
Workflow & Documentation
- Never create new documentation files without checking if an existing one should be updated
- Never leave documentation out of sync with code changes
- Never document implementation details that will quickly become stale
- Never write documentation that duplicates information available in code comments
- Never generate shell scripts that run rm -rf without explicit confirmation or safeguards
- Never suggest database migrations that could cause data loss without warnings
- Never propose changes that could break backward compatibility without flagging them
- Never execute destructive operations in production environments without explicit user confirmation
- Never suggest deprecated versions of frameworks or libraries
- Never add dependencies without justifying why they are necessary
- Never use packages with known security vulnerabilities
- Never pin to exact versions without explaining the reasoning
- Never assume the user's operating system; provide cross-platform solutions when possible
- Never use OS-specific commands without providing alternatives
- Never hardcode path separators; use path libraries instead
- Never assume specific shell environments (bash vs zsh vs PowerShell)
Framework-Specific Rules
Load the appropriate reference file based on the technology stack in use:
Languages
- TypeScript — See
references/typescript.md - Python — See
references/python.md
Web Frameworks
- React — See
references/react.md
Backend Frameworks
- NestJS — See
references/nestjs.md - Django — See
references/django.md - FastAPI — See
references/fastapi.md
Full-Stack Stacks
- React with TypeScript — See
references/react-typescript.md - Node.js Backend — See
references/node-backend.md - Docker & Containers — See
references/docker.md
Cloud & Infrastructure
- AWS CDK — See
references/aws-cdk.md - Supabase — See
references/supabase.md - Terraform — See
references/terraform.md
Modern Web
- Astro — See
references/astro.md - Remix — See
references/remix.md - Svelte — See
references/svelte.md
Mobile
- React Native — See
references/react-native.md - Flutter — See
references/flutter.md
Testing
- Vitest — See
references/vitest.md - Playwright — See
references/playwright.md - Cypress — See
references/cypress.md
AI Agents
- Claude Code — See
references/claude-code.md
How to Use
1. Always apply the core constraints above 2. Identify the technology stack from the project 3. Load the corresponding reference file(s) for framework-specific rules 4. Apply all relevant constraints when generating or editing code
Astro Constraints
Island Architecture
- Never hydrate components that do not need interactivity
- Never use client directives on static content
- Never load entire frameworks for simple interactions
- Always use
client:visiblefor below-fold interactive components - Always prefer
client:idleoverclient:loadfor non-critical interactivity - Always use
client:onlywhen SSR is not possible for a component
Content Collections
- Never use raw Markdown files when Content Collections can validate
- Never skip schema validation for content types
- Always define schemas with Zod in
src/content/config.ts - Always use
getCollection()andgetEntry()for type-safe content access - Always use frontmatter slugs consistently
Component Structure
- Never mix framework components without clear boundaries
- Never use framework-specific state as the primary data source
- Always keep Astro components for layout and structure
- Always use slots for flexible composition
- Always minimize JavaScript in Astro frontmatter
Styling
- Never use global styles that can conflict with component styles
- Always use scoped styles in Astro components by default
- Always use
is:globalsparingly for necessary global styles - Always prefer CSS variables for theming
Data Fetching
- Never fetch data on the client when it can be fetched at build time
- Never make API calls in component render without caching
- Always fetch data in Astro frontmatter for static pages
- Always use
Astro.cookiesandAstro.requestfor SSR needs - Always cache external API responses during build
Performance
- Never import unused framework adapters
- Never bundle large libraries without code splitting
- Always use image optimization with
astro:assetsand native<Image />component (Astro v3+) - Always prefetch critical pages with
<link rel="prefetch"> - Always analyze bundle size with
astro build --analyze
SEO and Metadata
- Never hardcode meta tags across pages; use a shared component
- Always use
<head>in layouts for consistent metadata - Always generate sitemaps with
@astrojs/sitemap - Always provide Open Graph and Twitter meta tags
Routing
- Never create dynamic routes without
getStaticPathsfor SSG - Always use file-based routing consistently
- Always define 404 pages at
src/pages/404.astro - Always use
[...slug].astrofor catch-all routes
Integrations
- Never add integrations without understanding their impact on build
- Always configure integrations in
astro.config.mjs - Always update integrations regularly for compatibility
Testing
- Never deploy without testing builds locally
- Always run
astro checkfor TypeScript validation - Always test responsive layouts across breakpoints
AWS CDK Constraints
Construct Levels
- Never use L1 constructs (Cfn*) when an L2 construct exists; L2 provides sensible defaults and better DX
- Never hardcode AWS account IDs or regions; use
Aws.ACCOUNT_IDandAws.REGIONtokens - Never create resources without explicit removal policies for stateful resources (databases, buckets)
- Always prefer L2 constructs over L1; only use L1 for features not yet in L2
- Always set
removalPolicy: RemovalPolicy.RETAINfor production databases and S3 buckets
Stack Organization
- Never create stacks with more than 500 resources; split into nested stacks or separate stacks
- Never use cross-stack references for frequently changing values; use SSM Parameter Store
- Never define resources in the constructor without checking for environment-specific conditions
- Always use separate stacks for stateful (databases) and stateless (lambdas) resources
- Always define clear stack dependencies using
stack.addDependency()
Resource Naming
- Never use auto-generated names for S3 buckets in production; specify explicit bucket names
- Never include sensitive information in resource names or tags
- Always use consistent naming conventions:
{app}-{env}-{resource-type}-{identifier} - Always add tags for cost allocation, environment, and ownership
Lambda Functions
- Never bundle node_modules for Lambda without tree-shaking; use
NodejsFunctionwith esbuild - Never set Lambda memory below 128MB or timeout above 15 minutes
- Never use
Functionconstruct for Node.js; useNodejsFunctionfor automatic bundling - Always configure reserved concurrency for critical functions to prevent throttling
- Always set appropriate timeout values based on expected execution time
Security
- Never use
AnyPrincipal()in IAM policies without explicit justification - Never grant
*permissions; follow principle of least privilege - Never store secrets in environment variables; use Secrets Manager or Parameter Store
- Always use
Grant*methods on resources instead of manual IAM policy creation - Always enable encryption at rest for S3, RDS, DynamoDB, and SNS/SQS
VPC and Networking
- Never create public subnets for databases or internal services
- Never use default VPC for production workloads
- Always use private subnets with NAT gateways for Lambda functions accessing the internet
- Always define security groups with minimal ingress rules
Aspects and Compliance
- Never skip compliance checks; use CDK Aspects for organization-wide policies
- Always implement custom Aspects for tagging compliance and security scanning
- Always run
cdk diffbeforecdk deployto review changes
Testing
- Never deploy without running
cdk synthto verify template generation - Always write snapshot tests for critical stacks using
Template.fromStack() - Always use assertions library to verify resource properties
Claude Code Agent Constraints
Package Management
- Never run
npm installwithout checking if the package is already inpackage.json; verify dependencies first - Never suggest a third-party library if a native solution exists; prefer built-in functionality to reduce dependencies
Autonomous Behavior
- Never ask for permission to edit a file if you are in Agent or Yolo mode; the user has opted into autonomous editing
- Never stop a task halfway through; if a file is too long, ask to break it up first before starting
Meta Files
- Never modify the
.cursorrulesorCLAUDE.mdfiles themselves unless specifically requested; these control agent behavior
Git Practices
- Never use vague commit messages like
UpdateorFix; always use descriptive, imperative titles - Never provide code snippets for a language not used in the repo; stay within the project's tech stack
Code Quality
- Never ignore linter warnings; fix them immediately as they signal future errors
- Never use the word "modern" or "best practice" as sole justification; explain the technical benefit
- Never create a mock if a real test utility is available; use actual testing utilities over mocks
Cypress Constraints
Selectors
- Never use selectors based on CSS styling; classes change frequently
- Never use fragile selectors like
:nth-child()or tag names alone - Never select by text that changes based on i18n
- Always use
data-cy,data-test, ordata-testidattributes - Always prefer selecting by accessible roles when possible
- Always use
cy.contains()for user-visible text when stable
Commands and Chaining
- Never use
cy.wait()with arbitrary numbers; use aliases or intercepts - Never mix async/await with Cypress commands; use chaining
- Never store Cypress command results in variables; use aliases
- Always chain commands for readability
- Always use
.then()for accessing yielded values - Always use
cy.wrap()when working with non-Cypress values
Custom Commands
- Never create overly generic custom commands
- Never duplicate Cypress built-in functionality
- Always add TypeScript definitions for custom commands
- Always name commands descriptively:
cy.loginAsAdmin() - Always keep commands focused on a single action
Network Handling
- Never rely on real network responses for unit-style tests
- Never use
cy.wait(1000)for network; usecy.intercept()aliases - Always use
cy.intercept()to stub or spy on network requests - Always alias intercepts and wait with
cy.wait('@alias') - Always test both success and error API responses
Assertions
- Never assert on internal implementation details
- Never use multiple unrelated assertions in one test
- Always use Chai-jQuery assertions for DOM elements
- Always assert on the user-visible outcome
- Always use
.should()for retrying assertions
Test Organization
- Never create dependencies between test files
- Never rely on test execution order
- Always isolate tests using
beforeEachhooks - Always use
describeblocks for logical grouping - Always keep tests atomic and independent
Fixtures and Data
- Never hardcode test data in test files; use fixtures
- Never share state between tests without explicit setup
- Always use
cy.fixture()for static test data - Always reset database/state in
beforeorbeforeEach - Always use factories for dynamic test data
Authentication
- Never go through login UI for every test
- Always use
cy.session()to cache and restore sessions - Always set cookies/localStorage directly for faster auth
Component Testing
- Never mount components without necessary providers
- Always use
cy.mount()for component testing - Always test component variations and edge cases
- Always mock external dependencies
Configuration
- Never hardcode environment-specific values
- Always use
cypress.config.tsfor configuration - Always use environment variables for sensitive data
- Always set appropriate viewport sizes for responsive testing
Debugging
- Never commit
.only()or.skip()without commented reason - Always use
cy.log()for debugging information - Always use
.debug()for interactive debugging - Always review screenshots and videos on failures
Django Constraints
Models
- Never use
null=Trueon CharField or TextField; useblank=Truewith default="" - Never define business logic in models that depends on request context
- Never use
ForeignKeywithout specifyingon_delete - Never access
requestor session data in model methods - Always add
db_index=Trueto fields used in filters and lookups - Always use
related_namefor ForeignKey and ManyToMany fields - Always define
__str__method for admin readability
Migrations
- Never edit migrations that have been applied to production
- Never delete migrations; create new ones to undo changes
- Never make data migrations in the same file as schema migrations
- Always run
makemigrations --checkin CI to catch missing migrations - Always review auto-generated migrations before committing
- Always use
RunPython.noopfor reverse migration when appropriate
Views and URLs
- Never put database queries in templates; prepare data in views
- Never use function-based views for complex logic; use class-based views
- Never hardcode URLs; use
reverse()or{% url %}tag - Always use
get_object_or_404()instead of manual exception handling - Always return proper HTTP status codes for API views
- Always use
LoginRequiredMixinor@login_requiredfor protected views
QuerySets and ORM
- Never use
.all()without limiting results in views - Never evaluate QuerySets in loops; use
select_related()andprefetch_related() - Never use
len(queryset)for counting; use.count() - Never use
.get()without try/except orget_object_or_404 - Always use
.only()or.defer()for large models - Always use
.exists()instead ofif queryset:for boolean checks - Always use
F()andQ()objects for complex queries
Forms
- Never trust user input without cleaning; use form validation
- Never save forms without calling
is_valid()first - Always use ModelForm for model-based forms
- Always implement
clean_<field>methods for field-specific validation - Always use CSRF protection for all forms
Security
- Never use
|safefilter on user-provided content without sanitization - Never interpolate user input into raw SQL; use ORM or parameterized queries
- Never store secrets in
settings.py; use environment variables - Always set
ALLOWED_HOSTSin production - Always use
django.contrib.authfor authentication - Always apply permission classes to API views
Admin
- Never expose admin in production without IP restrictions or 2FA
- Never use admin for end-user-facing functionality
- Always customize admin display with
list_display,list_filter,search_fields - Always use
readonly_fieldsfor computed or sensitive fields
Templates
- Never embed Python logic in templates; use template tags and filters
- Never load heavy data in template tags; pass from views
- Always use template inheritance with
{% extends %}and{% block %} - Always escape user content by default; Django does this automatically
Performance
- Never make database queries in loops
- Always use
select_relatedfor ForeignKey traversals in loops - Always use
prefetch_relatedfor ManyToMany and reverse FK - Always cache expensive queries using Django cache framework
Testing
- Never test against the production database
- Always use
TestCaseorTransactionTestCasefor database tests - Always use
ClientorAPIClientfor view tests - Always use factories (factory_boy) instead of fixtures for test data
Docker & Container Constraints
Security
- Never use
chmod 777in Dockerfiles; use minimum required permissions (e.g.,chmod 644for files,chmod 755for executables) - Never run containers as root user; use
USERdirective to run as non-privileged user - Never use
:latesttag in productionFROMstatements; pin to specific versions (e.g.,node:20.11.0-alpine) - Never store secrets in Dockerfile
ENVorARGdirectives; use Docker secrets or runtime environment variables - Never expose unnecessary ports to
0.0.0.0in docker-compose; bind to127.0.0.1or use internal networks
Build Optimization
- Never install development dependencies in production images; use multi-stage builds and
--productionflag - Never copy entire project directory with
COPY . .without a.dockerignore - Never use
apt-get upgradeorapk upgradewithout pinning package versions - Never run
apt-get updateandapt-get installin separateRUNcommands; combine them
Networking
- Never use
hostnetwork mode in production unless absolutely necessary - Never hardcode IP addresses or hostnames in containers; use Docker DNS service names or environment variables
Resource Management
- Never run containers without resource limits; set
mem_limit,cpus, or use Docker resource constraints - Never use unlimited restart policies without rate limiting; use
on-failure:5or similar
Logging & Debugging
- Never log sensitive data to stdout/stderr in containers; filter before logging
- Never use
docker execto modify running container state in production; containers should be immutable
Health & Monitoring
- Never deploy containers without health checks; define
HEALTHCHECKin Dockerfile - Never ignore container exit codes; monitor and alert on non-zero exits
FastAPI Constraints
Pydantic Models
- Never use
dictas request/response type; define Pydantic models - Never use
Anytype in model fields without explicit validation - Never allow arbitrary types without
Config.arbitrary_types_allowed - Always use
Field()for validation constraints and descriptions - Always define separate models for Create, Update, and Response schemas
- Always use
Config.from_attributes = Truefor ORM model conversion
Route Handlers
- Never put business logic directly in route handlers; use service layer
- Never use
async defwithout actual async operations; usedefinstead - Never return SQLAlchemy/ORM models directly; convert to Pydantic models
- Always use type hints for all parameters and return types
- Always specify response_model for automatic serialization and docs
- Always use appropriate HTTP status codes with
status_codeparameter
Dependency Injection
- Never instantiate database sessions manually in routes
- Never use global mutable state for request-scoped data
- Always use
Depends()for database sessions, auth, and shared logic - Always use
yielddependencies for cleanup (database sessions) - Always cache expensive dependencies with
@lru_cache
Authentication and Security
- Never store passwords in plain text; use
passlibwith bcrypt - Never include secrets in response models
- Never trust client-provided user IDs; extract from JWT
- Always use
OAuth2PasswordBeareror custom security dependencies - Always validate JWT tokens on every protected route
- Always use HTTPS in production
Error Handling
- Never return raw exceptions to clients
- Never use bare
except:clauses - Always use
HTTPExceptionwith appropriate status codes - Always define custom exception handlers for domain errors
- Always include detail messages that help debugging without exposing internals
Database Operations
- Never use synchronous ORM in async routes; use async drivers or run_in_threadpool
- Never commit transactions in utility functions; let the route handler manage
- Never execute N+1 queries; use eager loading or joinedload
- Always use dependency injection for database sessions
- Always handle
IntegrityErrorandNoResultFoundexplicitly
Request Validation
- Never use
request.json()directly; use Pydantic models - Never skip validation for file uploads
- Always use
Path(),Query(),Body()for parameter documentation - Always validate enum values with
LiteralorEnum - Always use
constr(),conint(), etc. for constrained types
Background Tasks
- Never run long operations in route handlers; use
BackgroundTasks - Never access request context in background tasks; pass data explicitly
- Always handle exceptions in background tasks; they fail silently
Documentation
- Never leave endpoints without descriptions and examples
- Always use
summaryanddescriptionparameters on routes - Always provide example values in Pydantic models
- Always tag endpoints for logical grouping in OpenAPI docs
Testing
- Never test against production database
- Always use
TestClientfor synchronous tests - Always use
httpx.AsyncClientfor async tests - Always override dependencies in tests with
app.dependency_overrides
Flutter Constraints
Widget Composition
- Never create deeply nested widget trees; extract into separate widgets
- Never put business logic inside build methods
- Never use StatefulWidget when StatelessWidget suffices
- Always keep widgets small and focused on one responsibility
- Always use const constructors for immutable widgets
- Always prefer composition over inheritance for widget reuse
State Management
- Never use setState for complex or shared state
- Never rebuild entire widget trees for localized state changes
- Never store derived state; compute it from source state
- Always use state management (Provider, Riverpod, Bloc) for complex apps
- Always scope state providers as narrowly as possible
- Always separate UI state from business logic
Performance
- Never call setState in build method
- Never use
print()in production; it impacts performance - Never create unnecessary widget rebuilds
- Always use
constkeyword for static widgets - Always use
ListView.builderfor long lists, notColumnwith children - Always profile with Flutter DevTools before optimizing
Layout
- Never hardcode dimensions; use responsive layouts
- Never nest
ColumninsideColumnwithoutExpandedorFlexible - Never use
MediaQueryin build without caching - Always use
ExpandedandFlexiblein Row/Column layouts - Always use
LayoutBuilderfor responsive widget sizing - Always handle overflow with
SingleChildScrollViewor clipping
Platform Channels
- Never block the main isolate with heavy computation
- Never pass large data synchronously through channels
- Always use async method channels
- Always handle platform exceptions gracefully
- Always test platform-specific code on real devices
Navigation
- Never push routes without proper back handling
- Never use string-based routing for complex navigation
- Always use Navigator 2.0 or go_router for complex navigation
- Always type-check route arguments
- Always handle deep links consistently
Assets and Images
- Never use network images without placeholders and error handling
- Never bundle unoptimized images
- Always use
cached_network_imagefor remote images - Always provide multiple asset resolutions (1x, 2x, 3x)
- Always preload critical images during splash screen
Error Handling
- Never swallow exceptions without logging
- Never show raw error messages to users
- Always use custom error widgets with
ErrorWidget.builder - Always implement crash reporting (Firebase Crashlytics, Sentry)
- Always use
try-catchfor async operations
Testing
- Never skip widget tests for critical UI components
- Always use
WidgetTesterfor widget testing - Always test golden images for visual regression
- Always use integration tests for critical user flows
- Always mock dependencies with
mocktailormockito
Code Organization
- Never mix feature code across directories
- Always organize by feature, not by type
- Always separate data, domain, and presentation layers
- Always use dependency injection for testability
Null Safety
- Never use
!operator without null check - Never use
latewithout guaranteed initialization - Always handle nullable types explicitly
- Always use null-aware operators appropriately
NestJS Constraints
Controllers
- Never put business logic in controllers; delegate to services
- Never inject more than 5 dependencies into a controller; refactor if needed
- Never return raw database entities; use DTOs or serializers
- Never use
@Res()decorator unless absolutely necessary; it disables interceptors - Always use versioning for API endpoints in production
- Always define route-specific DTOs for request validation
- Always use
@HttpCode()for non-200 success responses
Providers and Services
- Never use
anytype in service method signatures - Never catch and swallow exceptions silently; log or rethrow
- Never create tightly coupled services; use interfaces for abstraction
- Always mark services with
@Injectable()decorator - Always use constructor injection over property injection
- Always keep services focused on a single responsibility
Modules
- Never import modules circularly; use
forwardRef()only as last resort - Never export providers that are internal implementation details
- Never put all code in a single module; organize by feature
- Always create feature modules with their own controllers, services, and DTOs
- Always use
@Global()sparingly; prefer explicit imports - Always list all providers, controllers, imports, and exports explicitly
Dependency Injection
- Never use
newkeyword for injectable classes; let DI container manage them - Never access the DI container directly in production code
- Always use custom providers for third-party libraries
- Always scope providers appropriately (singleton, request, transient)
DTOs and Validation
- Never use entity classes as DTOs; create separate classes
- Never skip validation on incoming data
- Always use
class-validatordecorators on DTO properties - Always use
class-transformerwith@Exclude()for sensitive fields - Always implement
ValidationPipeglobally or per-controller
Guards and Middleware
- Never use guards for business logic; use only for authorization
- Never perform database queries in middleware
- Always place authentication guards before authorization guards
- Always use canActivate for route protection
Interceptors
- Never modify response structure inconsistently across endpoints
- Always use interceptors for cross-cutting concerns (logging, caching, transformation)
- Always handle both success and error cases in interceptors
Exception Handling
- Never expose stack traces or internal errors to clients in production
- Never throw generic
Error; use NestJS built-in exceptions - Always implement an exception filter for consistent error responses
- Always include error codes for client-side handling
Database
- Never execute raw SQL without parameterized queries
- Never load entire tables without pagination
- Always use transactions for multi-step database operations
- Always implement repository pattern or use TypeORM/Prisma repositories
Testing
- Never skip unit tests for services
- Always mock external dependencies in unit tests
- Always use the testing module for e2e tests
- Always test both success and error paths
Node.js Backend Constraints
Security
- Never store API keys or secrets in the codebase; always use environment variables
- Never use
eval()ornew Function(); these enable arbitrary code execution attacks - Never return raw database objects in API responses; use DTOs to prevent data leakage
- Never allow an API endpoint to return more than 100 items without pagination; implement limits to prevent OOM crashes
Error Handling
- Never write a
try/catchblock without logging the error to a structured logger; silent failures make debugging impossible
Performance
- Never use sync file operations like
readFileSyncin a request loop; use async operations to avoid blocking - Never perform database queries inside a
forEachloop; batch queries to prevent N+1 problems
Code Standards
- Never use hardcoded URLs; use a centralized config object for environment-specific values
- Never use CommonJS
require; always use ESMimport/exportfor better tree-shaking - Never mix package managers like yarn and npm; stick to one to avoid lockfile conflicts
Validation & Testing
- Never use Zod without enabling strict mode; permissive validation allows data pollution
- Never create a new API route without an accompanying
.test.tsfile; untested endpoints are technical debt
Playwright Constraints
Locators
- Never use CSS selectors based on styling classes; they change frequently
- Never use XPath unless absolutely necessary; prefer user-facing selectors
- Never use
page.$()orpage.$$()for interactions; use locators - Never use fragile selectors like
nth-childor positional indexes - Always prefer
getByRole(),getByText(),getByLabel(),getByTestId() - Always use
data-testidattributes for elements without semantic roles - Always chain locators for specificity:
page.getByRole('list').getByRole('listitem')
Page Object Model
- Never put assertions in page objects; only actions and locators
- Never expose locators directly; wrap them in meaningful methods
- Always use page objects for reusable page interactions
- Always return page objects from navigation methods for chaining
- Always keep page objects focused on a single page or component
Waiting and Synchronization
- Never use
page.waitForTimeout()for synchronization; use auto-waiting - Never use
setTimeoutorsleepin tests - Always rely on Playwright's built-in auto-waiting
- Always use
expect(locator).toBeVisible()for explicit waits when needed - Always use
page.waitForResponse()when waiting for API calls
Assertions
- Never use raw Jest/Node assertions; use Playwright's
expect - Never assert on implementation details; assert on user-visible outcomes
- Always use web-first assertions:
expect(locator).toHaveText() - Always test from the user's perspective
- Always include negative test cases (error states, edge cases)
Test Organization
- Never create dependencies between test files
- Never share state between tests without explicit fixtures
- Never run tests in a specific order; each test should be independent
- Always use
describeblocks to group related tests - Always use
beforeEachandafterEachfor setup and cleanup - Always keep tests focused and atomic
Fixtures
- Never use global state; use fixtures for shared setup
- Never repeat setup code across tests; extract to fixtures
- Always use worker fixtures for expensive setup (database, auth)
- Always use test fixtures for per-test isolation
- Always clean up after fixtures with proper teardown
Authentication
- Never log in through the UI in every test; use storage state
- Always use
storageStateto reuse authentication across tests - Always set up auth in a global setup file
API Testing
- Never mock APIs when testing API integrations
- Always use
requestfixture for API-only tests - Always validate response schemas and status codes
Configuration
- Never hardcode base URLs; use
playwright.config.ts - Always configure retries for flaky test handling
- Always use projects for cross-browser testing
- Always configure appropriate timeouts per project
Debugging
- Never commit
test.only()or.skip()without reason - Always use
npx playwright test --uifor debugging - Always generate and review trace files for failures
- Always use
page.pause()for interactive debugging
Python Constraints
Common Pitfalls
- Never use mutable default arguments (lists, dicts) in function definitions
- Never use bare
except:clauses; always catch specific exceptions - Never use
exec()oreval()with untrusted input - Never import with wildcard
from module import *
Type Hints
- Never omit type hints in function signatures for public APIs
- Never use
Anytype when a more specific type is possible - Never ignore type checker errors without documented justification
Code Style
- Never use camelCase for variable or function names; use snake_case
- Never use single-letter variable names except in comprehensions or lambdas
- Never mix tabs and spaces for indentation
- Never exceed 100 characters per line without strong justification
Best Practices
- Never use
isfor value comparison; use==(except for None, True, False) - Never modify a list while iterating over it
- Never use
assertfor data validation in production code - Never hardcode file paths; use pathlib or os.path
Modern Python
- Never use old-style string formatting (%) when f-strings are available
- Never use
dict.keys()ordict.values()when direct iteration works - Never import from
__future__unnecessarily in Python 3.10+ - Never use deprecated modules (e.g., optparse, imp)
React Native Constraints
Performance
- Never use inline functions in render; they cause unnecessary re-renders
- Never pass arrow functions directly to event handlers in lists
- Never use
console.login production; it causes performance issues - Never use index as key in FlatList; use unique identifiers
- Always use
useCallbackfor functions passed to child components - Always use
useMemofor expensive computations - Always use
React.memo()for pure functional components
FlatList Optimization
- Never use
ScrollViewfor long lists; useFlatListorSectionList - Never render all items in a large list; use virtualization
- Always implement
getItemLayoutwhen item heights are known - Always use
keyExtractorwith unique stable identifiers - Always set
initialNumToRender,maxToRenderPerBatch,windowSize - Always use
removeClippedSubviewsfor off-screen item optimization
Styling
- Never create StyleSheet objects inside components; define outside
- Never use inline styles for complex styling
- Never mix styled-components and StyleSheet inconsistently
- Always use
StyleSheet.create()for performance optimizations - Always use absolute positioning sparingly; prefer flexbox
- Always avoid shadows on Android; use elevation instead
Images
- Never use large unoptimized images; compress before bundling
- Never use remote images without placeholders
- Always use
resizeModeappropriately - Always cache remote images using libraries like
react-native-fast-image - Always provide width and height for remote images
Navigation
- Never store navigation state in Redux/global state
- Never use deep nesting of navigators without need
- Always use React Navigation or Expo Router
- Always type navigation props with TypeScript
- Always use
useFocusEffectfor screen-specific effects
State Management
- Never use Redux for simple local state; use useState/useReducer
- Never store derived state; compute it in render or useMemo
- Always use context for theme and auth; use state managers for complex state
- Always normalize nested data in stores
- Always use selectors to prevent unnecessary re-renders
Native Modules
- Never block the JS thread with heavy native calls
- Never pass large amounts of data across the bridge synchronously
- Always use TurboModules for new native modules (New Architecture)
- Always batch bridge communications when possible
- Always use JSI for performance-critical native interactions
Platform-Specific Code
- Never assume iOS behavior works on Android; test both
- Never use platform-specific APIs without proper checks
- Always use
Platform.select()for platform-specific values - Always use
.ios.tsxand.android.tsxfor divergent implementations - Always test on real devices, not just simulators
Error Handling
- Never let errors crash the app silently
- Always use error boundaries for component trees
- Always implement global error handlers with crash reporting
- Always handle network errors gracefully with retry logic
Animations
- Never animate on the JS thread for complex animations
- Always use
react-native-reanimatedfor performant animations - Always use native driver (
useNativeDriver: true) when possible - Always keep animations at 60fps; profile with Perf Monitor
Testing
- Never skip testing on real devices
- Always use React Native Testing Library for component tests
- Always use E2E testing (Detox, Maestro) for critical flows
- Always mock native modules in unit tests
React with TypeScript Constraints
Type Safety
- Never use
anytype in TypeScript; useunknownif the type is truly dynamic to maintain type safety - Never use
React.FCorReact.FunctionalComponenttypes; these are legacy and add unnecessary overhead
Component Architecture
- Never create a component over 150 lines; break it into sub-components for better testability
- Never use barrel files (
index.ts) for internal component folders; it breaks tree-shaking and creates circular dependencies
Data Fetching
- Never use
useEffectfor data fetching; use TanStack Query or Server Components to avoid waterfalls
Styling
- Never use inline styles; use Tailwind CSS classes exclusively for consistency
- Never use px values in Tailwind; use relative units like rem for better accessibility
Security
- Never use
localStoragefor sensitive state; use secure stores or httpOnly cookies - Never use
document.getElementByIdin React; use refs to work with React's virtual DOM
Code Standards
- Never use Default Exports; always use Named Exports for better refactoring support
- Never include
console.login production-bound code; use proper logging libraries
React Constraints
Component Architecture
- Never use Class Components; use Functional Components with hooks
- Never define components inside other components; creates new instances on each render
- Never use shouldComponentUpdate; use React.memo for memoization
- Never mutate props or state directly
Hooks
- Never call hooks conditionally or inside loops
- Never use useEffect without a dependencies array (unless intentional)
- Never forget to clean up side effects in useEffect return function
- Never use useState for values that can be derived from props or other state
Lists and Keys
- Never use array index as key for dynamic lists that can reorder
- Never use random values (Math.random, uuid on render) as keys
- Never omit keys when rendering arrays of elements
State Management
- Never lift state higher than necessary; keep it close to where it's used
- Never store derived state; compute it during render
- Never use useReducer for simple state; avoid it for trivial state unless testing or action semantics are needed
- Never pass too many props through components; consider context or composition
Performance
- Never create new object or array literals in props; causes unnecessary re-renders
- Never use inline function definitions in JSX for frequently re-rendered components
- Never forget to memoize expensive computations with useMemo
- Never wrap everything in React.memo; profile first to identify actual bottlenecks
Remix Constraints
Loaders
- Never fetch data on the client when loaders can provide it
- Never return sensitive data from loaders; filter on the server
- Never use
useEffectto fetch data available from loaders - Always use
loaderfunctions for page data requirements - Always return typed responses with
json()helper - Always handle authentication and authorization in loaders
Actions
- Never mutate data with GET requests; use POST/PUT/DELETE
- Never skip validation in action handlers
- Never redirect without returning a response
- Always use
actionfunctions for form submissions - Always return proper status codes and redirect after mutations
- Always validate and sanitize all action input
Forms
- Never use controlled inputs when uncontrolled work; leverage native forms
- Never prevent default form submission without reason
- Always use
<Form>component instead of<form>for navigation - Always use
<fetcher.Form>for non-navigating mutations - Always handle pending UI states with
useNavigation
Error Handling
- Never throw errors without error boundaries
- Never show raw error messages to users
- Always implement
ErrorBoundaryexports in routes - Always implement
CatchBoundaryfor expected errors (404, 403) - Always log errors server-side with context
Progressive Enhancement
- Never assume JavaScript is available
- Never break core functionality without JS
- Always ensure forms work without JavaScript first
- Always add JavaScript enhancements progressively
- Always test with JavaScript disabled
Route Organization
- Never create deeply nested routes without clear purpose
- Always use route file naming conventions consistently
- Always use
_index.tsxfor index routes - Always use dot notation for nested layouts (
routes/dashboard.settings.tsx)
Data Loading Patterns
- Never waterfall data requests; load in parallel
- Always use
deferfor slow data with streaming - Always use
Awaitcomponent with loading fallbacks - Always prefetch links with
<Link prefetch="intent">
Sessions and Auth
- Never store sensitive data in cookies without encryption
- Never trust client-side auth state alone
- Always use
createCookieSessionStorageor similar - Always verify session in loaders for protected routes
- Always set secure cookie options in production
TypeScript
- Never use
anyfor loader and action return types - Always type loader data with
LoaderFunctionArgs - Always use
useLoaderData<typeof loader>()for type inference - Always define types for form data and action responses
Performance
- Never load unnecessary JavaScript in routes
- Always use HTTP caching headers appropriately
- Always minimize client bundle with route-based code splitting
- Always use streaming for large responses
Testing
- Never skip testing loaders and actions
- Always test routes with
createRemixStubor integration tests - Always mock external services in tests
Supabase Constraints
Row Level Security (RLS)
- Never disable RLS on tables containing user data; it is the primary security layer
- Never use
SECURITY DEFINERfunctions without understanding privilege escalation risks - Never create policies with
USING (true)on sensitive tables - Always enable RLS immediately after creating any new table
- Always test RLS policies with different user contexts before deployment
- Always use
auth.uid()to scope queries to the authenticated user
Authentication
- Never store passwords or hash them yourself; use Supabase Auth exclusively
- Never expose service role key in client-side code; it bypasses RLS
- Never use the anon key for admin operations
- Always use
supabase.auth.getUser()to verify JWT on the server - Always configure email templates and redirect URLs in the dashboard
- Always enable email confirmation for production apps
Database Schema
- Never use
serialorbigserialfor primary keys; useuuidwithgen_random_uuid() - Never create tables without timestamps (
created_at,updated_at) - Never store files in database columns; use Supabase Storage
- Always add foreign key constraints with appropriate ON DELETE behavior
- Always create indexes on columns used in WHERE clauses and joins
- Always use
timestamptzinstead oftimestampfor timezone awareness
Storage
- Never make buckets public unless files are truly meant for unauthenticated access
- Never allow unrestricted file uploads; validate MIME types and sizes
- Always use signed URLs for temporary access to private files
- Always organize files with consistent path structures:
{bucket}/{user_id}/{resource_type}/{filename} - Always set appropriate bucket policies for upload/download permissions
Edge Functions
- Never expose secrets in Edge Function responses
- Never trust client-provided data without validation
- Always use
Deno.env.get()to access secrets - Always handle CORS appropriately for browser requests
- Always return appropriate HTTP status codes
Client Library
- Never create multiple Supabase client instances; use a singleton
- Never chain
.single()on queries that might return multiple rows - Always handle errors from all Supabase operations
- Always use TypeScript types generated from the database schema
- Always use
.select()to specify columns instead of selecting all
Realtime
- Never subscribe to entire tables in production; use filters
- Never leave subscriptions open after component unmounts
- Always unsubscribe in cleanup functions
- Always handle connection state changes
Performance
- Never fetch more data than needed; use pagination with
.range() - Never run queries in loops; use batch operations or joins
- Always use database functions for complex operations
- Always consider using Postgres views for complex queries
Migrations
- Never modify migrations that have been applied to production
- Never delete data without a backup strategy
- Always use the Supabase CLI for local development and migrations
- Always test migrations on a staging environment first
Svelte Constraints
Reactivity
- Never mutate objects/arrays without reassignment; reactivity requires it
- Never use
letfor values that should beconst - Never create reactive statements that cause infinite loops
- Always use
$:reactive declarations for derived values - Always reassign arrays/objects to trigger updates:
arr = [...arr, item] - Always use stores for shared/global state
Components
- Never create components larger than 200 lines; split them up
- Never use
$$propsor$$restPropswithout clear need - Always define
export letfor component props - Always use slots for flexible content composition
- Always emit events with
createEventDispatcher
Stores
- Never access store values without
$prefix in templates - Never forget to unsubscribe from custom subscriptions
- Never put async logic directly in stores
- Always use writable, readable, and derived appropriately
- Always use
$storesyntax for auto-subscription - Always create custom stores for complex state logic
Bindings
- Never overuse two-way bindings; they can cause unexpected updates
- Never bind to deeply nested properties
- Always use
bind:valuefor form inputs - Always use
bind:thissparingly for DOM access - Always prefer events over bindings for parent-child communication
Lifecycle
- Never access DOM before
onMount - Never forget cleanup in lifecycle hooks
- Always use
onMountfor browser-only code - Always return cleanup functions from lifecycle hooks
- Always use
onDestroyfor cleanup that must happen
SvelteKit Routing
- Never use client-side navigation for server-required actions
- Never expose sensitive data from server load functions
- Always use
+page.server.tsfor sensitive data loading - Always use
+layout.sveltefor shared UI - Always define load functions for data requirements
SvelteKit Forms
- Never skip form validation on the server
- Never trust client-side validation alone
- Always use form actions for mutations
- Always return proper form validation errors
- Always use
enhancefor progressive enhancement
Styling
- Never rely on global styles leaking into components
- Always use scoped styles by default
- Always use
:global()sparingly for external elements - Always use CSS variables for theming
Performance
- Never render large lists without virtualization (svelte-virtual-list)
- Never import entire libraries for small utilities
- Always use
{#key}blocks to force component recreation - Always use
{#await}for async data in templates - Always analyze bundle size with
vite-plugin-inspect
Transitions and Animations
- Never animate on page load without user preference check
- Always use
transition:,in:,out:directives - Always respect
prefers-reduced-motion - Always use
animate:for list reordering
TypeScript
- Never use
anyfor prop types - Always enable
lang="ts"in script blocks - Always type component props and events
- Always use
satisfiesfor type checking objects
Testing
- Never skip component testing
- Always use
@testing-library/sveltefor component tests - Always test reactive behavior with state changes
- Always use Playwright for E2E testing with SvelteKit
Terraform Constraints
Module Structure
- Never write inline resources in the root module; use child modules for reusability
- Never create modules with more than one logical resource group; keep modules focused
- Never hardcode values that vary by environment; use variables with validation
- Always structure modules with: main.tf, variables.tf, outputs.tf, versions.tf
- Always document modules with README.md including usage examples
State Management
- Never store state files locally for production; use remote backends (S3, GCS, Azure Blob)
- Never share state files between environments; use workspace isolation or separate state files
- Never manually edit .tfstate files; use
terraform statecommands - Always enable state locking using DynamoDB (AWS) or equivalent
- Always encrypt state at rest and in transit
Variables and Outputs
- Never use type
anyfor variables; always specify explicit types - Never leave variables without descriptions
- Never use default values for sensitive variables
- Always add validation blocks for variables with constraints
- Always mark sensitive outputs with
sensitive = true
Resource Naming
- Never use
countwhen resources have unique identities; usefor_eachwith maps - Never reference resources by index when order matters
- Always use consistent naming:
resource "type" "purpose_environment_qualifier" - Always use
localvalues to construct standardized resource names
Dependencies
- Never use
depends_onunless absolutely necessary; prefer implicit dependencies - Never create circular dependencies between modules
- Always output values that other resources or modules need
- Always use data sources to reference existing infrastructure
Provider Configuration
- Never hardcode credentials in provider blocks
- Never pin provider versions with
=; use~>for minor version flexibility - Never use multiple provider aliases without clear documentation
- Always specify required_providers with version constraints
- Always use environment variables or credential files for authentication
Security
- Never commit .tfvars files containing secrets to version control
- Never output sensitive values without the sensitive flag
- Never use
ignore_changesfor security-relevant attributes - Always use data sources to reference secrets from vaults
- Always enable versioning and access logging for state buckets
Workspaces
- Never use workspaces as a replacement for environment separation in large projects
- Always document workspace naming conventions
- Always use consistent variable values per workspace
Code Quality
- Never skip
terraform fmtbefore committing - Never ignore
terraform validateerrors - Always run
terraform planand review before apply - Always use pre-commit hooks for formatting and validation
- Always run security scanners like tfsec or checkov in CI
TypeScript Constraints
Type Safety
- Never use
anytype; always aim for strict typing with proper interfaces or generics - Never use type assertions (as) to bypass type checking without justification
- Never disable TypeScript strict mode or individual strict checks
- Never use @ts-ignore or @ts-expect-error without a comment explaining why
Variable Declarations
- Never use
var; always useconstorlet - Never use
letwhenconstwould suffice - Never declare variables without initializing them when type inference is possible
Modern Syntax
- Never use string concatenation for building SQL queries or dynamic code
- Never use callbacks when async/await is available
- Never use
.then()chains when async/await would be clearer - Never use
argumentsobject; use rest parameters instead
Best Practices
- Never disable ESLint rules inline without strong justification
- Never export mutable variables; export functions or immutable values
- Never use non-null assertion (!) without checking for null/undefined first
- Never mix different module systems (CommonJS and ES modules) in the same project
React/JSX (when applicable)
- Never use string refs; use useRef or createRef
- Never access .current on a ref without null checking
- Never define components inside other components
Vitest Constraints
Test Structure
- Never use
test.only()ordescribe.only()in committed code - Never create tests that depend on execution order
- Never share mutable state between tests
- Always use
describeblocks to group related tests - Always write descriptive test names that explain the expected behavior
- Always follow the Arrange-Act-Assert (AAA) pattern
Assertions
- Never use multiple unrelated assertions in one test
- Never write assertions that always pass
- Always use specific matchers:
toEqual,toStrictEqual,toContain - Always test both positive and negative cases
- Always assert on error messages and types, not just that errors are thrown
Mocking
- Never mock what you do not own without clear documentation
- Never leave mocks in place across tests; reset in
beforeEachorafterEach - Never mock implementation details; mock boundaries (APIs, databases)
- Always use
vi.mock()at the module level for ES modules - Always use
vi.spyOn()for observing calls without changing behavior - Always call
vi.restoreAllMocks()inafterEachwhen using spies
Async Testing
- Never use
donecallback when async/await is available - Never forget to await promises in async tests
- Always use async/await for asynchronous tests
- Always set appropriate timeouts for slow async operations
- Always use
vi.waitFor()for testing async state changes
Coverage
- Never aim for 100% coverage at the expense of meaningful tests
- Never write tests just to hit coverage thresholds
- Always focus coverage on critical business logic
- Always configure coverage thresholds in vitest.config.ts
- Always exclude test files and generated code from coverage
Snapshot Testing
- Never use snapshots for frequently changing output
- Never blindly update snapshots without reviewing changes
- Always keep snapshots small and focused
- Always use inline snapshots for short expected values
- Always review snapshot diffs in pull requests
Setup and Teardown
- Never perform heavy setup in
beforeEachthat can be inbeforeAll - Never skip cleanup; leaked state causes flaky tests
- Always use
beforeEachfor test-specific setup - Always use
afterEachto reset mocks and cleanup - Always use
beforeAll/afterAllfor expensive one-time setup
Test Files
- Never put test files far from source files; co-locate when possible
- Always use
.test.tsor.spec.tsextension consistently - Always mirror source file structure in test organization
- Always import from source using the same paths as production code
Performance
- Never run expensive operations in tests without isolation
- Always use
vi.useFakeTimers()for time-dependent code - Always run tests in parallel when possible (default in Vitest)
- Always use in-source testing for tiny utility functions
Debugging
- Never leave
console.logstatements in committed tests - Always use
test.todo()for planned tests - Always use
--reporter=verbosefor debugging failures - Always use
--inspect-brkfor debugger attachment