# Development Guide

Welcome to the Feuerwehr Dashboard development guide. This document will help you get started with developing, testing, and contributing to the project.

## Table of Contents

- [Developer Onboarding](#developer-onboarding)
- [Local Development Setup](#local-development-setup)
- [Project Structure](#project-structure)
- [Code Architecture](#code-architecture)
- [Development Workflow](#development-workflow)
- [Adding New Features](#adding-new-features)
- [Testing Guidelines](#testing-guidelines)
- [Debugging](#debugging)
- [Common Issues](#common-issues)
- [Best Practices](#best-practices)

## Developer Onboarding

### Prerequisites

Before you begin, ensure you have:

- **Node.js 18+** - [Download](https://nodejs.org/)
- **Docker Desktop** - [Download](https://www.docker.com/products/docker-desktop)
- **Git** - [Download](https://git-scm.com/)
- **Code Editor** - VS Code recommended
- **Authentik Access** - For testing authentication

### Recommended VS Code Extensions

```json
{
  "recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "ms-vscode.vscode-typescript-next",
    "bradlc.vscode-tailwindcss",
    "ms-azuretools.vscode-docker",
    "prisma.prisma"
  ]
}
```

### First Steps

1. **Clone the repository**:
   ```bash
   git clone <repository-url>
   cd feuerwehr_dashboard
   ```

2. **Read the documentation**:
   - [README.md](README.md) - Project overview
   - [ARCHITECTURE.md](ARCHITECTURE.md) - System design
   - [API_DOCUMENTATION.md](API_DOCUMENTATION.md) - API reference

3. **Set up your environment** (see below)

4. **Run the application** locally

5. **Make a small change** to familiarize yourself with the codebase

## Local Development Setup

### Option 1: Docker-Based Development (Recommended for Beginners)

Start the development database:

```bash
make dev
```

This starts only PostgreSQL, allowing you to run backend/frontend locally with hot reload.

### Option 2: Fully Dockerized (Quick Testing)

Run everything in Docker:

```bash
make prod
```

Note: This doesn't support hot reload, so it's less ideal for active development.

### Option 3: Native Development (Full Control)

#### Step 1: Start Database

```bash
make dev
```

Or manually:

```bash
docker-compose -f docker-compose.dev.yml up -d
```

#### Step 2: Configure Backend

Create `backend/.env`:

```bash
cd backend
cat > .env << EOF
DATABASE_URL=postgresql://dev_user:dev_password@localhost:5432/feuerwehr_dev
JWT_SECRET=dev_secret_do_not_use_in_production
NODE_ENV=development
PORT=3000
LOG_LEVEL=debug

# Authentik - use your dev instance
AUTHENTIK_CLIENT_ID=your_dev_client_id
AUTHENTIK_CLIENT_SECRET=your_dev_client_secret
AUTHENTIK_ISSUER=http://localhost:9000/application/o/feuerwehr/
AUTHENTIK_REDIRECT_URI=http://localhost:5173/auth/callback
EOF
```

#### Step 3: Install Backend Dependencies

```bash
cd backend
npm install
```

#### Step 4: Run Backend

```bash
npm run dev
```

Backend will start on `http://localhost:3000` with auto-reload on file changes.

#### Step 5: Configure Frontend

Create `frontend/.env`:

```bash
cd frontend
cat > .env << EOF
VITE_API_URL=http://localhost:3000
EOF
```

#### Step 6: Install Frontend Dependencies

```bash
cd frontend
npm install
```

#### Step 7: Run Frontend

```bash
npm run dev
```

Frontend will start on `http://localhost:5173` with hot module replacement.

### Verify Setup

Test backend:
```bash
curl http://localhost:3000/health
# Should return: {"status":"ok","timestamp":"..."}
```

Test frontend:
```bash
open http://localhost:5173
# Browser should open with login page
```

## Project Structure

### Backend Structure

```
backend/
├── src/
│   ├── config/              # Configuration files
│   │   ├── database.ts      # Database connection and pool
│   │   ├── environment.ts   # Environment variables
│   │   └── oauth.ts         # OAuth/Authentik configuration
│   ├── controllers/         # Request handlers
│   │   ├── auth.controller.ts
│   │   └── user.controller.ts
│   ├── database/
│   │   └── migrations/      # SQL migration files
│   │       ├── 001_create_users_table.sql
│   │       └── 002_create_sessions_table.sql
│   ├── middleware/          # Express middleware
│   │   ├── auth.middleware.ts      # Authentication
│   │   ├── error.middleware.ts     # Error handling
│   │   └── rate-limit.middleware.ts # Rate limiting
│   ├── models/              # Data models
│   │   └── user.model.ts
│   ├── routes/              # API routes
│   │   ├── auth.routes.ts
│   │   └── user.routes.ts
│   ├── services/            # Business logic
│   │   ├── auth.service.ts
│   │   ├── oauth.service.ts
│   │   ├── token.service.ts
│   │   └── user.service.ts
│   ├── types/               # TypeScript types
│   │   ├── auth.types.ts
│   │   └── user.types.ts
│   ├── utils/               # Utility functions
│   │   └── logger.ts
│   ├── app.ts               # Express app configuration
│   └── server.ts            # Server entry point
├── logs/                    # Application logs (gitignored)
├── Dockerfile
├── package.json
├── tsconfig.json
└── nodemon.json
```

### Frontend Structure

```
frontend/
├── src/
│   ├── components/          # Reusable React components
│   │   ├── common/          # Shared components
│   │   │   ├── Header.tsx
│   │   │   └── Loading.tsx
│   │   └── layout/          # Layout components
│   │       └── MainLayout.tsx
│   ├── contexts/            # React Context providers
│   │   └── AuthContext.tsx  # Authentication state
│   ├── pages/               # Page components
│   │   ├── auth/
│   │   │   ├── LoginPage.tsx
│   │   │   └── CallbackPage.tsx
│   │   ├── dashboard/
│   │   │   └── DashboardPage.tsx
│   │   └── user/
│   │       └── ProfilePage.tsx
│   ├── services/            # API service layer
│   │   ├── api.ts           # Axios instance
│   │   ├── authService.ts   # Auth API calls
│   │   └── userService.ts   # User API calls
│   ├── theme/               # MUI theme configuration
│   │   └── theme.ts
│   ├── types/               # TypeScript types
│   │   └── auth.types.ts
│   ├── utils/               # Utility functions
│   │   └── storage.ts       # Local storage helpers
│   ├── App.tsx              # Main app component
│   ├── main.tsx             # Entry point
│   └── vite-env.d.ts        # Vite type declarations
├── public/                  # Static assets
├── nginx.conf               # Production Nginx config
├── Dockerfile
├── package.json
├── vite.config.ts
└── tsconfig.json
```

## Code Architecture

### Backend Architecture

#### Layered Architecture

1. **Routes Layer** (`routes/`)
   - Define API endpoints
   - Input validation (Zod schemas)
   - Route to controllers

2. **Controllers Layer** (`controllers/`)
   - Handle HTTP requests/responses
   - Call services for business logic
   - Format responses

3. **Services Layer** (`services/`)
   - Business logic implementation
   - Database operations
   - External API calls (OAuth)

4. **Models Layer** (`models/`)
   - Data structures
   - Database queries
   - Data validation

5. **Middleware Layer** (`middleware/`)
   - Authentication
   - Error handling
   - Rate limiting
   - Logging

#### Request Flow

```
Client Request
    ↓
Express Router (routes/)
    ↓
Middleware (auth, validation)
    ↓
Controller (controllers/)
    ↓
Service (services/)
    ↓
Model (models/)
    ↓
Database
    ↓
← Response flows back up
```

### Frontend Architecture

#### Component-Based Architecture

1. **Pages** - Route-level components
2. **Layouts** - Structural components (header, sidebar)
3. **Components** - Reusable UI elements
4. **Contexts** - Global state management
5. **Services** - API communication

#### Data Flow

```
User Interaction
    ↓
Component Event Handler
    ↓
Service Layer (API call)
    ↓
Backend API
    ↓
Update Context/State
    ↓
Re-render Components
```

### Authentication Flow

```
1. User clicks "Login"
   ↓
2. Frontend redirects to Authentik
   ↓
3. User authenticates with Authentik
   ↓
4. Authentik redirects to /auth/callback with code
   ↓
5. Frontend sends code to backend /api/auth/callback
   ↓
6. Backend exchanges code for tokens with Authentik
   ↓
7. Backend creates user session in database
   ↓
8. Backend returns JWT access/refresh tokens
   ↓
9. Frontend stores tokens and updates AuthContext
   ↓
10. User is redirected to dashboard
```

## Development Workflow

### 1. Create Feature Branch

```bash
git checkout -b feature/your-feature-name
# or
git checkout -b fix/bug-description
```

### 2. Make Changes

- Write code following style guidelines
- Add comments for complex logic
- Update types as needed

### 3. Test Locally

```bash
# Run backend tests
cd backend && npm test

# Run frontend tests
cd frontend && npm test

# Manual testing
# Test in browser at http://localhost:5173
```

### 4. Commit Changes

```bash
git add .
git commit -m "feat: add user profile editing feature"
```

Follow [Conventional Commits](https://www.conventionalcommits.org/):
- `feat:` - New feature
- `fix:` - Bug fix
- `docs:` - Documentation
- `refactor:` - Code refactoring
- `test:` - Adding tests
- `chore:` - Maintenance

### 5. Push and Create PR

```bash
git push origin feature/your-feature-name
```

Create pull request on your Git platform.

## Adding New Features

### Adding a New API Endpoint

#### Step 1: Define Types

Create or update `backend/src/types/your-feature.types.ts`:

```typescript
export interface YourFeature {
  id: number;
  name: string;
  createdAt: Date;
}

export interface CreateYourFeatureDto {
  name: string;
}
```

#### Step 2: Create Model

Create `backend/src/models/your-feature.model.ts`:

```typescript
import { pool } from '../config/database';
import { YourFeature } from '../types/your-feature.types';

export const createYourFeature = async (name: string): Promise<YourFeature> => {
  const result = await pool.query(
    'INSERT INTO your_features (name) VALUES ($1) RETURNING *',
    [name]
  );
  return result.rows[0];
};
```

#### Step 3: Create Service

Create `backend/src/services/your-feature.service.ts`:

```typescript
import * as YourFeatureModel from '../models/your-feature.model';
import { CreateYourFeatureDto } from '../types/your-feature.types';

class YourFeatureService {
  async create(dto: CreateYourFeatureDto) {
    // Business logic here
    return await YourFeatureModel.createYourFeature(dto.name);
  }
}

export default new YourFeatureService();
```

#### Step 4: Create Controller

Create `backend/src/controllers/your-feature.controller.ts`:

```typescript
import { Request, Response } from 'express';
import yourFeatureService from '../services/your-feature.service';

class YourFeatureController {
  async create(req: Request, res: Response) {
    try {
      const feature = await yourFeatureService.create(req.body);
      res.status(201).json(feature);
    } catch (error) {
      res.status(500).json({ error: 'Failed to create feature' });
    }
  }
}

export default new YourFeatureController();
```

#### Step 5: Create Routes

Create `backend/src/routes/your-feature.routes.ts`:

```typescript
import { Router } from 'express';
import yourFeatureController from '../controllers/your-feature.controller';
import { authenticate } from '../middleware/auth.middleware';

const router = Router();

router.post('/', authenticate, yourFeatureController.create);

export default router;
```

#### Step 6: Register Routes

Update `backend/src/app.ts`:

```typescript
import yourFeatureRoutes from './routes/your-feature.routes';

app.use('/api/your-features', yourFeatureRoutes);
```

#### Step 7: Create Database Migration

Create `backend/src/database/migrations/00X_create_your_features_table.sql`:

```sql
CREATE TABLE IF NOT EXISTS your_features (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_your_features_name ON your_features(name);
```

### Adding a New Frontend Page

#### Step 1: Create Page Component

Create `frontend/src/pages/your-feature/YourFeaturePage.tsx`:

```typescript
import React from 'react';
import { Container, Typography } from '@mui/material';

const YourFeaturePage: React.FC = () => {
  return (
    <Container>
      <Typography variant="h4">Your Feature</Typography>
    </Container>
  );
};

export default YourFeaturePage;
```

#### Step 2: Create Service

Create `frontend/src/services/yourFeatureService.ts`:

```typescript
import api from './api';

export const createYourFeature = async (name: string) => {
  const response = await api.post('/api/your-features', { name });
  return response.data;
};
```

#### Step 3: Add Route

Update `frontend/src/App.tsx`:

```typescript
import YourFeaturePage from './pages/your-feature/YourFeaturePage';

// In your routes
<Route path="/your-feature" element={<YourFeaturePage />} />
```

## Testing Guidelines

### Backend Testing

Create `backend/src/__tests__/your-feature.test.ts`:

```typescript
import yourFeatureService from '../services/your-feature.service';

describe('YourFeatureService', () => {
  test('should create feature', async () => {
    const feature = await yourFeatureService.create({ name: 'Test' });
    expect(feature.name).toBe('Test');
  });
});
```

Run tests:
```bash
cd backend
npm test
```

### Frontend Testing

Create `frontend/src/__tests__/YourFeaturePage.test.tsx`:

```typescript
import { render, screen } from '@testing-library/react';
import YourFeaturePage from '../pages/your-feature/YourFeaturePage';

test('renders your feature page', () => {
  render(<YourFeaturePage />);
  expect(screen.getByText('Your Feature')).toBeInTheDocument();
});
```

Run tests:
```bash
cd frontend
npm test
```

### Manual Testing Checklist

- [ ] Feature works in development mode
- [ ] Feature works in production build
- [ ] Authenticated users can access
- [ ] Unauthorized access is blocked
- [ ] Error states are handled
- [ ] Loading states are shown
- [ ] Responsive on mobile
- [ ] Works in Chrome, Firefox, Safari

## Debugging

### Backend Debugging

#### VS Code Launch Configuration

Create `.vscode/launch.json`:

```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Debug Backend",
      "runtimeExecutable": "npm",
      "runtimeArgs": ["run", "dev"],
      "cwd": "${workspaceFolder}/backend",
      "console": "integratedTerminal"
    }
  ]
}
```

#### Console Logging

```typescript
import logger from '../utils/logger';

logger.debug('Debug message', { data });
logger.info('Info message');
logger.warn('Warning message');
logger.error('Error message', { error });
```

#### Database Queries

Enable query logging in `backend/src/config/database.ts`:

```typescript
const pool = new Pool({
  // ...config
  log: (msg) => logger.debug(msg)
});
```

### Frontend Debugging

#### React DevTools

Install [React Developer Tools](https://react.dev/learn/react-developer-tools) browser extension.

#### Console Logging

```typescript
console.log('Data:', data);
console.error('Error:', error);
```

#### Network Tab

Use browser DevTools Network tab to inspect API calls.

#### State Debugging

```typescript
const [state, setState] = useState(initialState);

useEffect(() => {
  console.log('State changed:', state);
}, [state]);
```

## Common Issues

### Database Connection Failed

**Problem**: Backend can't connect to database

**Solution**:
```bash
# Verify database is running
docker ps | grep postgres

# Restart database
docker-compose -f docker-compose.dev.yml restart

# Check logs
docker logs feuerwehr_db_dev
```

### Port Already in Use

**Problem**: Port 3000 or 5173 already occupied

**Solution**:
```bash
# Find process using port
lsof -i :3000

# Kill process
kill -9 <PID>

# Or change port in package.json
```

### TypeScript Errors

**Problem**: Type errors in VS Code

**Solution**:
```bash
# Restart TypeScript server in VS Code
# Cmd+Shift+P > "TypeScript: Restart TS Server"

# Rebuild
cd backend && npm run build
cd frontend && npm run build
```

### Authentik Redirect Fails

**Problem**: OAuth callback returns error

**Solution**:
1. Verify redirect URI exactly matches in Authentik
2. Check client ID and secret in `.env`
3. Ensure Authentik is accessible from browser
4. Check browser console for CORS errors

### Hot Reload Not Working

**Problem**: Changes don't reflect immediately

**Solution**:
```bash
# Backend - check nodemon is running
# Frontend - restart Vite dev server
npm run dev
```

## Best Practices

### Code Style

- Use TypeScript strict mode
- Follow ESLint rules
- Use Prettier for formatting
- Write descriptive variable names
- Add JSDoc comments for public APIs

### Security

- Never commit secrets to Git
- Validate all inputs
- Use parameterized queries
- Sanitize user input
- Keep dependencies updated

### Performance

- Use database indexes
- Implement pagination for lists
- Cache expensive operations
- Optimize bundle size
- Use React.memo for expensive components

### Git Workflow

- Keep commits small and focused
- Write clear commit messages
- Rebase before merging
- Delete branches after merge
- Don't commit `node_modules/` or `.env`

## Getting Help

- **Documentation**: Check all `.md` files
- **Code Comments**: Read inline documentation
- **Team Chat**: Ask in development channel
- **GitHub Issues**: Search existing issues
- **Stack Overflow**: Search for similar problems

## Next Steps

After completing setup:

1. Explore the codebase
2. Try adding a simple feature
3. Read [ARCHITECTURE.md](ARCHITECTURE.md)
4. Review [API_DOCUMENTATION.md](API_DOCUMENTATION.md)
5. Check [CONTRIBUTING.md](CONTRIBUTING.md)

Happy coding!
