# Contributing to DSS

Thank you for your interest in contributing to DSS (Design System Server)! This document provides guidelines and instructions for contributing.

## Table of Contents

- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Development Setup](#development-setup)
- [How to Contribute](#how-to-contribute)
- [Coding Standards](#coding-standards)
- [Testing](#testing)
- [Submitting Changes](#submitting-changes)
- [Release Process](#release-process)

## Code of Conduct

Be respectful, inclusive, and professional. We're all here to build great software together.

## Getting Started

1. **Fork the repository** on GitHub
2. **Clone your fork** locally
3. **Create a branch** for your changes
4. **Make your changes** and commit them
5. **Push to your fork** and submit a pull request

## Development Setup

### Prerequisites

- Python 3.10 or higher
- pip (Python package manager)
- git

### Quick Setup

```bash
# Clone your fork
git clone https://github.com/YOUR_USERNAME/dss.git
cd dss

# Run automated setup
./setup.sh

# Or manual setup:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

### Environment Configuration

1. Copy `.env.example` to `.env`
2. Add your Figma token (optional for most development)
3. Adjust any other settings as needed

```bash
cp .env.example .env
# Edit .env and add your FIGMA_TOKEN
```

### Running Tests

```bash
# Run all tests
pytest

# Run specific test file
pytest tests/test_ingestion.py

# Run with coverage
pytest --cov=tools --cov-report=html
```

### Running the Servers

```bash
# REST API (port 3456)
python -m tools.api.server

# MCP Server (port 3457) - in another terminal
python -m tools.api.mcp_server
```

## How to Contribute

### Types of Contributions

We welcome many types of contributions:

- 🐛 **Bug reports** - Found a bug? Open an issue
- ✨ **Feature requests** - Have an idea? Open an issue to discuss
- 📝 **Documentation** - Improve or add documentation
- 🧪 **Tests** - Add test coverage
- 🔧 **Bug fixes** - Fix reported bugs
- ⚡ **Performance** - Optimize existing code
- 🎨 **Code cleanup** - Refactoring and improvements

### Before You Start

1. **Search existing issues** - Someone might already be working on it
2. **Open an issue first** for major changes - Discuss the approach
3. **Keep changes focused** - One feature/fix per PR
4. **Follow coding standards** - See below

## Coding Standards

### Python Style

We follow **PEP 8** with some flexibility:

```python
# Good
def extract_tokens(source: str) -> TokenCollection:
    """Extract design tokens from source.

    Args:
        source: Source file path or content

    Returns:
        TokenCollection with extracted tokens
    """
    pass

# Bad - missing types and docstring
def extract_tokens(source):
    pass
```

### Type Hints

Use type hints for all public APIs:

```python
from typing import List, Optional, Dict, Any

def parse_css(content: str) -> List[DesignToken]:
    ...

async def fetch_data(url: str) -> Optional[Dict[str, Any]]:
    ...
```

### Docstrings

All modules, classes, and public functions need docstrings:

```python
"""
Module docstring describing purpose.
"""

class TokenMerger:
    """
    Merges token collections with conflict resolution.

    Usage:
        merger = TokenMerger(strategy=MergeStrategy.LAST)
        result = merger.merge([col1, col2])
    """

    def merge(self, collections: List[TokenCollection]) -> MergeResult:
        """
        Merge multiple token collections.

        Args:
            collections: List of TokenCollection to merge

        Returns:
            MergeResult with merged tokens and conflict information
        """
        pass
```

### Error Handling

Use specific exceptions, never bare `except:`

```python
# Good
try:
    data = json.loads(content)
except (json.JSONDecodeError, KeyError) as e:
    logger.error(f"Failed to parse: {e}")
    return None

# Bad
try:
    data = json.loads(content)
except:  # Never use bare except!
    return None
```

### Naming Conventions

- **Classes**: PascalCase (`TokenMerger`, `ProjectScanner`)
- **Functions/Methods**: snake_case (`extract_tokens`, `merge_collections`)
- **Constants**: UPPER_SNAKE_CASE (`MAX_RETRIES`, `DEFAULT_PORT`)
- **Private**: Leading underscore (`_internal_method`, `_cache`)

### File Organization

```
tools/
├── module_name/
│   ├── __init__.py          # Public API exports
│   ├── base.py              # Abstract base classes
│   ├── core.py              # Main implementation
│   └── utils.py             # Helper functions
```

## Testing

### Writing Tests

Place tests in the `tests/` directory:

```python
# tests/test_feature.py
import pytest
from tools.module import Feature

def test_basic_functionality():
    """Test basic feature works."""
    feature = Feature()
    result = feature.process("input")
    assert result == "expected"

@pytest.mark.asyncio
async def test_async_feature():
    """Test async operations."""
    feature = Feature()
    result = await feature.async_process()
    assert result is not None
```

### Test Coverage

- Aim for **80%+ coverage** for new code
- Test both success and failure cases
- Test edge cases and invalid input
- Use fixtures for common setup

### Running Specific Tests

```bash
# Run single test
pytest tests/test_ingestion.py::test_css_ingestion

# Run tests matching pattern
pytest -k "test_merge"

# Run with verbose output
pytest -v

# Run with coverage
pytest --cov=tools --cov-report=term-missing
```

## Submitting Changes

### Commit Messages

Write clear, descriptive commit messages:

```
Add token merge conflict resolution

- Implement PREFER_FIGMA strategy
- Add conflict tracking to MergeResult
- Update documentation with examples

Fixes #123
```

Format:
- **First line**: Brief summary (50 chars or less)
- **Blank line**
- **Body**: Detailed explanation (wrap at 72 chars)
- **References**: Link to issues

### Pull Request Process

1. **Update your branch** with latest main
   ```bash
   git checkout main
   git pull upstream main
   git checkout your-branch
   git rebase main
   ```

2. **Run tests** and ensure they pass
   ```bash
   pytest
   ```

3. **Update documentation** if needed
   - Update CHANGELOG.md
   - Update README.md if adding features
   - Add docstrings to new code

4. **Push to your fork**
   ```bash
   git push origin your-branch
   ```

5. **Open a Pull Request** on GitHub
   - Fill out the PR template
   - Link related issues
   - Add screenshots for UI changes

### PR Review Process

- Maintainers will review within 1-3 days
- Address review feedback
- Once approved, we'll merge your PR
- Your contribution will be in the next release! 🎉

## Development Workflow

### Creating a Feature

```bash
# 1. Create branch
git checkout -b feature/amazing-feature

# 2. Make changes
# Edit files...

# 3. Test
pytest

# 4. Commit
git add .
git commit -m "Add amazing feature"

# 5. Push and create PR
git push origin feature/amazing-feature
```

### Fixing a Bug

```bash
# 1. Create branch
git checkout -b fix/issue-123

# 2. Write failing test
# tests/test_bug.py

# 3. Fix the bug
# tools/module/file.py

# 4. Verify test passes
pytest tests/test_bug.py

# 5. Commit and PR
git commit -m "Fix issue #123: Description"
```

## Release Process

Maintainers handle releases:

1. Update version in relevant files
2. Update CHANGELOG.md
3. Create release tag
4. Publish to package registry
5. Announce release

## Questions?

- **Bug reports**: Open an issue
- **Feature requests**: Open an issue for discussion
- **General questions**: Open a discussion
- **Security issues**: Email security@example.com

## Recognition

All contributors are recognized in our:
- README.md contributors section
- Release notes
- CHANGELOG.md

Thank you for contributing to DSS! 🚀
