5.4 KiB
5.4 KiB
Coding Standards
Last Updated: January 2025
Project: Moyos Wedding App
File and Folder Naming
Files
- Components:
kebab-case.tsx(e.g.,rsvp-form.tsx,guest-card.tsx) - Utilities:
kebab-case.ts(e.g.,request-id.ts,rate-limit.ts) - API Routes:
route.ts(Next.js App Router convention) - Types:
kebab-case.tsor in feature folders astypes.ts
Folders
- Feature folders:
kebab-case(e.g.,rsvp/,guestbook/) - Component folders:
kebab-case(e.g.,features/,ui/) - Utility folders:
kebab-case(e.g.,lib/,hooks/)
Type Definitions
Location
- Global types:
src/types/index.ts - Feature-specific types: Co-located in feature folders (e.g.,
src/components/features/rsvp/types.ts) - API types: Co-located with API routes or in
src/types/api.ts
Naming
- Interfaces:
PascalCase(e.g.,GuestSession,RsvpFormData) - Types:
PascalCase(e.g.,ApiResponse<T>,AuditEventType) - Enums:
PascalCase(e.g.,ReportType,ExportFormat)
Hooks
Naming
- All hooks: Must be prefixed with
use(e.g.,useGuest,useRealtime,useMobile) - File names:
use-kebab-case.ts(e.g.,use-guest.ts,use-realtime.ts)
Location
- Global hooks:
src/hooks/ - Feature-specific hooks: Co-located in feature folders (e.g.,
src/components/features/rsvp/use-rsvp.ts)
Components
Naming
- Component files:
kebab-case.tsx(e.g.,rsvp-form.tsx) - Component names:
PascalCase(e.g.,RsvpForm,GuestCard) - Props interfaces:
ComponentNameProps(e.g.,RsvpFormProps)
Organization
- Feature components:
src/components/features/{feature-name}/ - UI components:
src/components/ui/ - Layout components:
src/components/layout/
API Routes
Structure
- Route handlers:
src/app/api/{route}/route.ts - Request validation: Use Zod schemas in
src/lib/validators/ - Error handling: Standardized error responses
- Logging: Use
loggerwith request ID context
Naming
- Route files:
route.ts(Next.js convention) - Validator files:
{feature}-validators.ts(e.g.,rsvp-validators.ts)
State Management
Single Source of Truth
- Guest state:
src/context/guest-context.tsx - Admin state: To be centralized (currently scattered)
- No duplicate state: Avoid storing same data in multiple places
Imports
Order
- React/Next.js imports
- Third-party library imports
- Internal component imports
- Internal utility imports
- Type imports (with
typekeyword) - Relative imports
Example
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { verifyGuestSession } from '@/lib/auth';
import { logger } from '@/lib/logger';
import type { GuestSession } from '@/types';
Code Style
TypeScript
- No
anytypes: Use proper types orunknown - Strict mode: Enabled
- Type imports: Use
import typefor type-only imports
Functions
- Async functions: Always handle errors with try-catch
- Error logging: Use
logger.error()with context - Request ID: Include in all log contexts
Validation
- All API inputs: Must use Zod validation
- Schemas: Co-located in
src/lib/validators/
Testing
File Naming
- Unit tests:
*.test.tsor*.test.tsx - E2E tests:
*.spec.ts - Location: Co-located with source files in
__tests__/folders
Coverage
- Minimum: 60% global coverage
- Critical utilities: 100% coverage (sanitize, csrf, rate-limit)
- API routes: 80%+ coverage
Documentation
Comments
- Complex logic: Add explanatory comments
- API routes: JSDoc comments for exported functions
- Types: Document complex types with comments
README Files
- Feature folders: Optional
README.mdfor complex features - Main docs: In
docs/folder
Git Commits
Format
- Type:
feat:,fix:,chore:,refactor:,docs:,test: - Scope: Optional feature name
- Message: Clear, concise description
Examples
feat: add request ID tracking to middlewarefix: correct Zod validation error handlingchore: remove unused @sendgrid/mail dependencyrefactor: consolidate duplicate RSVP form components
Security
Secrets
- Never commit:
.env.local,.env.production - Always validate: Use Zod schemas for env variables
- No client-side secrets: Never use
NEXT_PUBLIC_*for secrets
Input Validation
- All inputs: Validate with Zod
- File uploads: Validate magic bytes, size, type
- Sanitization: Use
sanitize.tsutilities
Performance
Code Splitting
- Large components: Use
next/dynamicfor lazy loading - Admin components: Always lazy loaded
- Heavy libraries: Lazy load when possible
Caching
- API responses: Use SWR for client-side caching
- Database queries: Add indexes, optimize queries
- Static data: Cache in Redis when available
Accessibility
ARIA Labels
- Interactive elements: Always include aria-labels
- Form inputs: Associated labels
- Error messages: Announced to screen readers
Keyboard Navigation
- All interactive elements: Keyboard accessible
- Focus management: Proper focus handling
This document should be updated as patterns evolve.