# Contributing to FastAPI + Next.js Template
First off, thank you for considering contributing to this project! 🎉
This template aims to be a rock-solid foundation for full-stack applications, and your contributions help make that possible.
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [How Can I Contribute?](#how-can-i-contribute)
- [Development Setup](#development-setup)
- [Coding Standards](#coding-standards)
- [Testing Guidelines](#testing-guidelines)
- [Commit Messages](#commit-messages)
- [Pull Request Process](#pull-request-process)
---
## Code of Conduct
This project is committed to providing a welcoming and inclusive environment. We expect all contributors to:
- Be respectful and considerate
- Welcome newcomers and help them learn
- Focus on constructive criticism
- Accept feedback gracefully
- Prioritize the community's well-being
Unacceptable behavior includes harassment, trolling, insulting comments, and personal attacks.
---
## How Can I Contribute?
### Reporting Bugs
Found a bug? Help us fix it!
1. **Check existing issues** to avoid duplicates
2. **Create a new issue** with:
- Clear, descriptive title
- Steps to reproduce
- Expected vs. actual behavior
- Environment details (OS, Python/Node version, etc.)
- Screenshots/logs if applicable
### Suggesting Features
Have an idea for improvement?
1. **Check existing issues/discussions** first
2. **Open a discussion** to gauge interest
3. **Explain the use case** and benefits
4. **Consider implementation complexity**
Remember: This is a *template*, not a full application. Features should be:
- Broadly useful
- Well-documented
- Thoroughly tested
- Maintainable long-term
### Improving Documentation
Documentation improvements are always welcome!
- Fix typos or unclear explanations
- Add examples or diagrams
- Expand on complex topics
- Update outdated information
- Translate documentation (future)
### Contributing Code
Ready to write some code? Awesome!
1. **Pick an issue** (or create one)
2. **Comment** that you're working on it
3. **Fork and branch** from `main`
4. **Write code** following our standards
5. **Add tests** (required for features)
6. **Update docs** if needed
7. **Submit a PR** with clear description
---
## Development Setup
### Backend Development
```bash
cd backend
# Install dependencies (uv manages virtual environment automatically)
uv sync
# Setup environment
cp .env.example .env
# Edit .env with your settings
# Run migrations
python migrate.py apply
# Run tests
IS_TEST=True uv run pytest
# Start dev server
uvicorn app.main:app --reload
```
### Frontend Development
```bash
cd frontend
# Install dependencies
npm install
# Setup environment
cp .env.local.example .env.local
# Generate API client
npm run generate:api
# Run tests
npm test
npm run test:e2e:ui
# Start dev server
npm run dev
```
---
## Coding Standards
### Backend (Python)
- **Style**: Follow PEP 8
- **Type hints**: Use type annotations
- **Async**: Use async/await for I/O operations
- **Documentation**: Docstrings for all public functions/classes
- **Error handling**: Use custom exceptions appropriately
- **Security**: Never trust user input, validate everything
Example:
```python
async def get_user_by_email(
db: AsyncSession,
*,
email: str
) -> Optional[User]:
"""
Get user by email address.
Args:
db: Database session
email: User's email address
Returns:
User if found, None otherwise
"""
result = await db.execute(
select(User).where(User.email == email)
)
return result.scalar_one_or_none()
```
### Frontend (TypeScript/React)
- **Style**: Use Prettier (configured)
- **TypeScript**: Strict mode, no `any` types
- **Components**: Functional components with hooks
- **Naming**: PascalCase for components, camelCase for functions
- **Imports**: Use absolute imports with `@/` alias
- **Dependencies**: Use provided auth context (never import stores directly)
Example:
```typescript
interface UserProfileProps {
userId: string;
}
export function UserProfile({ userId }: UserProfileProps) {
const { user } = useAuth();
const { data, isLoading } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});
if (isLoading) return