# Coding Conventions

**Analysis Date:** 2026-02-15

## Naming Patterns

**Files:**
- Frontend pages: PascalCase with `.jsx` extension (e.g., `Dashboard.jsx`, `LoginPage.jsx`, `WorkoutPage.jsx`)
- Frontend components: PascalCase with `.jsx` extension (e.g., `Icons.jsx`)
- Backend routes: `index.js` for main server file
- CSS files: kebab-case or match component name (e.g., `index.css`, `App.css`)
- Context files: Named with `Context` suffix (e.g., `AuthContext.jsx`)

**Functions:**
- Async functions: verb + noun pattern (e.g., `fetchProgram`, `fetchLogs`, `handleSubmit`)
- Event handlers: `handle` prefix (e.g., `handleSubmit`, `handleSave`, `handleChange`)
- Helper/utility functions: descriptive names without prefixes (e.g., `getCoachGreeting`, `getMuscleGroups`, `getWeekStart`)
- Hook usage: Standard React hooks (e.g., `useState`, `useEffect`, `useContext`)
- Middleware functions: descriptive names (e.g., `authMiddleware`)

**Variables:**
- State variables: camelCase (e.g., `user`, `loading`, `program`, `selectedDay`)
- Constants (config): UPPER_SNAKE_CASE or camelCase (e.g., `API_URL`, `JWT_SECRET`, `PORT`)
- Local variables: camelCase (e.g., `dayOfWeek`, `todayWorkout`, `lastWeight`)
- Boolean variables: descriptive (e.g., `loading`, `editing`, `warmupDone`, `completedWarmups`)
- IDs: numeric or snake_case from database (e.g., `user_id`, `program_exercise_id`, `program_day_id`)

**Types:**
- Objects/interfaces: use descriptive structure without explicit types (e.g., `{ id, email, onboarding_complete }`)
- Database records: snake_case field names from schema (e.g., `password_hash`, `body_fat_pct`, `measured_at`)

## Code Style

**Formatting:**
- No explicit linter/formatter detected in config
- Indentation: 2 spaces (observed in code)
- Line length: typically under 100 characters
- Quotes: single quotes in most files, double quotes in some (inconsistent but not enforced)
- Semicolons: inconsistently used (some files omit, some include)

**Linting:**
- No ESLint, Prettier, or Biome config files detected
- No type checking (no TypeScript or JSDoc type annotations)

**Spacing:**
- Components separated by blank lines
- Function logic blocks separated by comments
- Import statements grouped: React/library imports first, then local imports

## Import Organization

**Order:**
1. React and core library imports (e.g., `import React from 'react'`)
2. External libraries (e.g., `react-router-dom`, Express packages)
3. Local imports (context, pages, components)
4. CSS/asset imports (e.g., `import './index.css'`)

**Path Aliases:**
- No path aliases configured (`@/` style paths not used)
- Relative imports used throughout (e.g., `'./context/AuthContext'`, `'../components/Icons'`)
- Relative paths: `../` for parent directory navigation in page imports

**Examples:**
```javascript
// Frontend (AuthContext.jsx)
import { createContext, useContext, useState, useEffect } from 'react';
import { useAuth } from '../context/AuthContext';
import { Icon } from '../components/Icons';
import './App.css';

// Backend (index.js)
const express = require('express');
const { Pool } = require('pg');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
```

## Error Handling

**Patterns:**
- **Frontend (React):** Try-catch blocks in async functions, error state managed with `useState`
  ```javascript
  try {
    const res = await fetch(`${API_URL}/auth/login`, { ... });
    const data = await res.json();
    if (!res.ok) throw new Error(data.error);
    // Handle success
  } catch (err) {
    setError(err.message);
  }
  ```

- **Backend (Express):** Try-catch blocks in route handlers with status code responses
  ```javascript
  try {
    // Database query or logic
    res.json(result);
  } catch (err) {
    if (err.code === '23505') return res.status(400).json({ error: 'Email already exists' });
    console.error('Operation error:', err);
    res.status(500).json({ error: 'Server error' });
  }
  ```

- **Error Response Format:** JSON with `error` key: `{ error: 'Human-readable message' }`
- **Status Codes:** 400 (validation/conflict), 401 (auth), 404 (not found), 500 (server error)
- **Empty error catches:** Some empty catch blocks without logging (e.g., `catch { logout(); }` in AuthContext)

## Logging

**Framework:** Native `console.error()` only

**Patterns:**
- Error logging: `console.error('Context + error:', err)`
- Backend operations logged: `console.error('Register error:', err)`, `console.error('Profile error:', err)`
- Frontend operations: minimal logging (mostly silent failures)
- No structured logging or log levels (DEBUG, INFO, WARN)
- Log format: descriptive label + colon + error object

**Examples from code:**
```javascript
console.error('Failed to fetch program:', err);
console.error('Login error:', err);
console.error('Update profile error:', err);
```

## Comments

**When to Comment:**
- Section headers for major logical blocks (e.g., `// Coach section`, `// Today's action`, `// Quick stats`)
- Data structure explanations (e.g., `// Uppvärmningsövningar baserat på muskelgrupp`)
- Complex calculations or business logic
- Not applied to simple conditionals or obvious code

**JSDoc/TSDoc:**
- Not used - no type annotations or formal documentation
- Inline comments rare and minimal

**Examples:**
```javascript
// Mappa övningar till muskelgrupper
function getMuscleGroups(exercises) { ... }

// Beräkna progress
const completedExercises = exercises.filter(ex => { ... });

// Check if log exists for this set
const existing = await pool.query(...);
```

## Function Design

**Size:**
- Page/component functions: 40-250 lines (includes JSX)
- Helper functions: 5-30 lines
- Backend route handlers: 10-50 lines

**Parameters:**
- Named parameters for component props: `{ children, requireOnboarding = true }`
- Function parameters: individual arguments or destructured objects
- Query parameters: destructured from request (e.g., `const { user_id, date } = req.query`)

**Return Values:**
- React components return JSX directly
- Async functions return Promise<JSON | null>
- Helper functions return computed values or arrays
- Route handlers return via `res.json()` or `res.status().json()`

**Async/Await:**
- Preferred over `.then()` chains
- Used consistently in all async operations
- Combined with try-catch for error handling

**Examples:**
```javascript
const fetchProgram = async () => {
  if (program) return; // Early return
  try {
    const res = await fetch(`${API_URL}/programs/1`);
    const data = await res.json();
    setProgram(data);
  } catch (err) {
    console.error('Failed to fetch program:', err);
  }
};

// Helper function
function isSameDay(d1, d2) {
  return d1.getDate() === d2.getDate() &&
         d1.getMonth() === d2.getMonth() &&
         d1.getFullYear() === d2.getFullYear();
}
```

## Module Design

**Exports:**
- Frontend: Default exports for pages/contexts: `export default Dashboard`
- Frontend: Named exports for utilities: `export const useAuth = () => useContext(AuthContext)`
- Backend: Direct route handlers with `app.get()`, `app.post()` etc. (not module exports)
- Contexts: `export function AuthProvider` + `export const useAuth`

**Barrel Files:**
- Icons component (`Icons.jsx`) exports multiple icon definitions and helper functions
- Most modules single-responsibility (one component/context per file)

**Examples:**
```javascript
// Context export pattern
export function AuthProvider({ children }) { ... }
export const useAuth = () => useContext(AuthContext);

// Component export pattern
export default function LoginPage() { ... }

// Backend (no module export pattern, direct app routing)
app.post('/api/auth/login', async (req, res) => { ... });
```

## State Management

**Frontend:**
- React `useState` hooks for local component state
- React Context API for global auth state (`AuthContext.jsx`)
- Parent component state passed down as props (e.g., `App.jsx` manages view, program, logs)
- No Redux, Zustand, or Jotai

**Backend:**
- In-memory database connections via `Pool` (pg package)
- No state persistence between requests
- Request-scoped data via middleware (e.g., `req.user` from JWT)

## CSS/Styling

**Approach:** Plain CSS with CSS variables
- CSS variables defined in `:root`: `--bg-primary`, `--text-primary`, `--accent`, etc.
- Dark theme with fitness-oriented color palette
- Classes: descriptive kebab-case (e.g., `dashboard-header`, `calendar-day`, `page-main`)
- Utility/modifier classes: `.active`, `.today`, `.has-workout`, `.loading`
- No CSS-in-JS or utility framework (no Tailwind, Styled Components)

---

*Convention analysis: 2026-02-15*
