# Contributing to Django MCP

We welcome contributions! Here's how to get started.

## Development Setup

```bash
git clone https://github.com/django-mcp/django-mcp.git
cd django-mcp

# Create virtual environment
uv venv
source .venv/bin/activate

# Install with dev dependencies
uv pip install -e ".[dev]"
```

## Running Tests

```bash
# Run all tests
pytest

# With coverage
pytest --cov=src/drf_mcp

# Watch mode (requires pytest-watch)
ptw

# Specific test file
pytest tests/test_schema.py

# Specific test
pytest tests/test_schema.py::TestSchemaConverter::test_simple_schema_generation
```

## Code Quality

```bash
# Format code
black src/drf_mcp tests
isort src/drf_mcp tests

# Linting
flake8 src/drf_mcp tests

# Type checking
mypy src/drf_mcp

# All checks
make lint  # if Makefile exists
```

## Documentation

```bash
# Build docs
cd docs
sphinx-build -b html . _build/html

# View locally
open _build/html/index.html
```

## Commit Guidelines

Follow [Conventional Commits](https://www.conventionalcommits.org/):

```
feat(discovery): Add recursive URLconf scanning
fix(executor): Handle async view execution properly
docs: Update getting started guide
test: Add integration tests for provider
refactor: Simplify schema converter logic
```

Types:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation
- `test`: Tests
- `refactor`: Code refactoring
- `perf`: Performance improvement
- `ci`: CI/CD changes
- `chore`: Maintenance

## Pull Request Process

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/your-feature`
3. Make your changes
4. Write/update tests
5. Run quality checks: `black`, `mypy`, `pytest`
6. Commit with conventional message
7. Push to your fork
8. Open a PR with description

## Architecture Guidelines

### Module Organization

```
src/drf_mcp/
├── discovery.py      # URLconf scanning
├── schema.py         # Serializer -> JSON schema
├── executor.py       # View execution
├── provider.py       # FastMCP provider
├── auth.py          # Auth utilities
├── server.py        # High-level API
└── management/
    └── commands/
        └── mcp_inspector.py
```

### Code Style

- **Type hints**: All public functions must have type hints
- **Docstrings**: Google-style docstrings for modules, classes, functions
- **Line length**: 100 characters (black default)
- **Imports**: Organized by isort (stdlib, third-party, local)
- **Constants**: UPPERCASE_WITH_UNDERSCORES

Example:

```python
def invoke(
    self,
    view_class: Type[APIView],
    method: str,
    path: str,
    data: Optional[Dict[str, Any]] = None,
    user: Optional[Any] = None,
) -> Any:
    """
    Invoke a DRF view method asynchronously.
    
    Args:
        view_class: DRF APIView or ViewSet class
        method: HTTP method name (GET, POST, etc.)
        path: URL path for the request
        data: Request payload (for POST/PUT/PATCH)
        user: Django User object for authentication
        
    Returns:
        Response data from view
        
    Raises:
        PermissionDenied: If user lacks required permissions
        ValueError: If method is invalid
    """
```

### Testing Guidelines

- Test file names: `test_*.py`
- Test class names: `Test*`
- Test method names: `test_*`
- Use fixtures for setup
- Mock external dependencies
- Test both happy path and error cases

```python
import pytest
from rest_framework.test import APIRequestFactory

@pytest.fixture
def factory():
    return APIRequestFactory()

@pytest.mark.django_db
class TestMyFeature:
    def test_success_case(self, factory):
        # Arrange
        request = factory.get('/test/')
        
        # Act
        result = my_function(request)
        
        # Assert
        assert result is not None
```

## Performance

- Use Django query optimization (`select_related`, `prefetch_related`)
- Cache expensive operations (URLconf scanning, schema generation)
- Profile with `django-silk` if needed
- Benchmark critical paths

## Security

- No hardcoded secrets
- Validate all inputs
- Never bypass permission checks
- Use Django's ORM (no raw SQL)
- Follow OWASP guidelines

## Documentation

- Update docstrings when changing APIs
- Update guides if behavior changes
- Add examples for new features
- Keep README.md current
- Document breaking changes in migration guide

## Issues

- Check existing issues before opening new ones
- Include minimal reproducible example
- Specify versions (Python, Django, DRF, etc.)
- Describe expected vs. actual behavior

## Code Review

All contributions require review. We look for:
- Code quality and style compliance
- Test coverage
- Documentation updates
- No breaking changes (or documented migrations)
- Performance implications

## Support

- Documentation: See [docs/](../docs/)
- Issues: [GitHub Issues](https://github.com/django-mcp/django-mcp/issues)
- Discussions: [GitHub Discussions](https://github.com/django-mcp/django-mcp/discussions)

## License

By contributing, you agree that your contributions will be licensed under the MIT License.

---

Thank you for contributing to Django MCP! 🎉
