# Coding Conventions

**Analysis Date:** 2026-01-11

## Naming Patterns

**Files:**
- React components: `JK{ComponentName}.js` (JamKazam brand prefix)
- Examples: `JKDashboardMain.js`, `JKTimeAgo.js`, `JKSessionModal.js` in `jam-ui/src/components/`
- Non-JK components: `PascalCase.js` (e.g., `Avatar.js`, `FalconCardHeader.js`)
- Test files: `*.test.js` (Jest unit tests), `*.spec.ts` (Playwright E2E), `*.spec.rb` (RSpec)

**Functions:**
- camelCase for all functions: `getPersonById()`, `getUserDetail()`, `createAffiliatePartner()`
- Examples in `jam-ui/src/helpers/rest.js`
- Async functions: No special prefix (async/await pattern used)
- Event handlers: `handle{EventName}` pattern (e.g., `handleClick`, `handleSubmit`)

**Variables:**
- camelCase for variables: `firstName`, `loadingExperiences`, `classNames`
- State variables: `const [firstName, setFirstName] = useState('Anthony');`
- Constants: UPPERCASE convention not strictly enforced, but used for module-level constants

**Types:**
- Interfaces/Types: PascalCase, no `I` prefix
- React PropTypes: Imported and used for component prop validation
- Example from `jam-ui/src/components/common/Avatar.js`: `import PropTypes from 'prop-types';`

## Code Style

**Formatting:**
- Prettier enforced via `.prettierrc` in `jam-ui/`
- Single quotes: `true` (use `'string'` not `"string"`)
- Print width: `120` characters
- Indentation: 2 spaces (standard Prettier default)
- Semicolons: Not explicitly configured, follows Prettier defaults

**Linting:**
- ESLint with `.eslintrc.json` in `jam-ui/`
- Extends: `react-app`, `prettier`, `plugin:react/recommended`
- Plugins: `prettier`
- Rule enforcement: `prettier/prettier` set to `error`
- Exception: `react/no-unescaped-entities` disabled

## Import Organization

**Order:**
1. React/core libraries (e.g., `react`, `react-dom`)
2. Third-party packages (e.g., `prop-types`, `@fortawesome/react-fontawesome`)
3. Internal/relative imports (e.g., `../../helpers/utils`)
4. Styles (if applicable)

**Example from `jam-ui/src/components/common/Avatar.js`:**
```javascript
import React from 'react';
import PropTypes from 'prop-types';
import { isIterableArray } from '../../helpers/utils';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
```

**Grouping:**
- Blank lines between import groups
- Alphabetical within groups (not strictly enforced)

**Path Aliases:**
- No custom path aliases configured
- Relative imports used throughout (`../../`, `../`)

## Error Handling

**Patterns:**
- Promise-based error handling with `.catch()` or `try/catch` for async/await
- Rails backend: Exceptions bubble to `api_controller.rb` base class
- Frontend: Errors caught in `apiFetch()` wrapper, returned as rejected promises
- Background jobs: Resque retry logic for transient failures

**Error Types:**
- API errors: Returned as JSON with status codes
- Client errors: Logged to console (development), reported to Bugsnag (production)
- Validation errors: Handled by ActiveRecord validations, returned in API responses

## Logging

**Framework:**
- Rails logger for backend (configured in `web/config/environments/`)
- Console logging for frontend (`console.log`, `console.error`)
- Bugsnag for production error tracking (API key in `web/config/application.rb`)

**Patterns:**
- Log at controller/action boundaries in Rails
- Minimal logging in frontend (removed in production builds)
- InfluxDB for time-series metrics (configured but disabled for production)

## Comments

**When to Comment:**
- Explain "why" not "what": Complex business logic, non-obvious algorithms
- TODO comments: Mark incomplete features or planned improvements
- FIXME comments: Mark known issues requiring fixes
- XXX comments: Mark questionable code requiring review

**JSDoc/PropTypes:**
- PropTypes used for React component prop validation
- JSDoc not extensively used, code is generally self-documenting
- Test files have header comments describing purpose

**TODO Comments:**
- Format: `// TODO: description` or `# TODO: description`
- Examples: `// TODO: Expose jamClient globally for debugging. This is temporarily added. Remove it later.`
- No username or issue tracking in TODO comments

## Function Design

**Size:**
- Keep functions under 100 lines where practical
- Extract complex logic into helper functions
- Example: Large helpers like `MixerHelper.js` (1,270 lines) contain multiple related functions

**Parameters:**
- Destructure object parameters in function signature
- Example: `const Avatar = ({ size, rounded, src, name, emoji, className }) => { ... }`
- Options objects for 4+ parameters: `function update(id, options) { ... }`

**Return Values:**
- Explicit return statements
- Promise-based returns for async operations
- Example: `return new Promise((resolve, reject) => { ... })`

## Module Design

**Exports:**
- Named exports preferred: `export const functionName = () => { ... }`
- Default exports for React components (not universal)
- Barrel exports via `index.js` files (not extensively used)

**React Components:**
- Functional components with hooks (React 16.13.1+)
- Arrow function syntax: `const Component = (props) => { ... }`
- PropTypes at bottom of file
- Example component structure:
  ```javascript
  import React from 'react';
  import PropTypes from 'prop-types';

  const Avatar = ({ size, src, name }) => {
    return <div>...</div>;
  };

  Avatar.propTypes = {
    size: PropTypes.string,
    src: PropTypes.string,
    name: PropTypes.string
  };

  export default Avatar;
  ```

**Ruby/Rails Patterns:**
- Class-based models inheriting from `ActiveRecord::Base`
- Controller actions follow RESTful conventions
- Snake_case for file names, method names, variables
- CamelCase for class names

---

*Convention analysis: 2026-01-11*
*Update when patterns change*
