Skip to main content

Coding Conventions

Mobile Client (TypeScript)

ESLint Rules (Enforced)

RuleSettingRationale
max-lines-per-function70Extract sub-components or hooks when functions grow
max-params3Use an object parameter for 4+ args
unicorn/filename-casekebab-caseConsistent file naming
@typescript-eslint/consistent-type-importsRequiredUse import type for type-only imports
simple-import-sortEnabledAutomatically sorted imports

Style Guidelines

  • Named exports preferred over default exports
  • Absolute imports with @/ prefix (e.g., @/components/ui)
  • Use function keyword for pure functions; functional components only (no classes)
  • Prefer type over interface; avoid enums (use as const objects)
  • Use Control<any> (not generic Control<T>) in custom form components
  • Forms use react-hook-form + Zod for validation

File Organization

src/
├── api/ # Server API layer
├── app/ # Expo Router screens
├── components/ # UI components grouped by feature
│ └── ui/ # Shared primitives
├── db/ # Database layer
│ ├── schema/ # Table definitions
│ ├── repositories/ # CRUD functions
│ └── hooks/ # React Query hooks
├── lib/ # Utilities and stores
├── translations/ # i18n files
└── types/ # Shared types

Component Patterns

  • Components grouped by feature in components/ subdirectories
  • Shared UI primitives in components/ui/
  • Forms use react-hook-form with Zod schema validation
  • Styling via NativeWind (Tailwind CSS classes)
  • Lists use React.memo for performance

Server (Python)

Dependency Management

Use uv for all Python dependency management (not pip or poetry):

uv sync              # Install dependencies
uv add <package> # Add a dependency
uv add --dev <pkg> # Add a dev dependency
uv run pytest # Run with uv

Django Patterns

  • All viewsets with user FK filter by user=request.user
  • Use IsOwner permission from common.permissions for object-level checks
  • Shared base classes: TimestampMixin and SyncMixin from common.models
  • StandardPagination (20 items/page) from common.pagination
  • Categories with user=None are system defaults visible to all users

Testing

  • Use shared pytest fixtures from conftest.py: user, other_user, api_client, auth_client, other_auth_client
  • Test files live in each app or in app-level tests/ directories
  • Use factory_boy for test data generation

Git

  • Conventional commits enforced by commitlint
  • Prefixes: feat:, fix:, chore:, refactor:, test:, docs:, perf:, style:
  • Lowercase, max 100 characters