Thank you for your interest in contributing to Canairy! We believe that early warning systems should be accessible to all families, and your contributions help make that possible.
- Code of Conduct
- How Can I Contribute?
- Development Setup
- Pull Request Process
- Coding Standards
- Testing Guidelines
- Documentation
- Community
We are committed to providing a welcoming and inclusive environment. Please read our Code of Conduct before contributing.
Before creating bug reports, please check existing issues to avoid duplicates. When creating a bug report, include:
- Clear title and description
- Steps to reproduce
- Expected vs actual behavior
- Screenshots (if applicable)
- Environment details (OS, browser, version)
- Error messages and console logs
We welcome feature suggestions! Please provide:
- Use case: Who benefits and how?
- Expected behavior: How should it work?
- Mockups/examples: Visual aids help!
- Priority rationale: Why is this important?
- Find an issue: Look for issues labeled
good first issueorhelp wanted - Comment: Let us know you're working on it
- Fork & Branch: Create a feature branch
- Code: Follow our standards
- Test: Add/update tests
- Document: Update relevant docs
- Submit PR: Follow the template
Adding new indicators or data sources:
- Research: Ensure data is reliable and accessible
- Implement Collector: Follow the collector template
- Add Tests: Include mock data for testing
- Document: Update data sources documentation
- Consider Fallbacks: What if the primary source fails?
- Node.js 18+ and npm
- Python 3.10+
- Git
- Docker (optional, for full stack)
-
Clone your fork
git clone https://github.com/YOUR_USERNAME/canairy.git cd canairy -
Install dependencies
# Frontend npm install # Backend cd backend pip install -r requirements.txt
-
Set up environment
cp .env.example .env # Add your API keys for testing -
Run development servers
# Terminal 1: Frontend npm run dev # Terminal 2: Backend cd backend uvicorn main:app --reload
-
Run tests
# Frontend tests npm test # Backend tests cd backend pytest
# Run full stack
docker-compose up
# Run with hot reload
docker-compose -f docker-compose.dev.yml up- Code follows style guidelines
- Self-review completed
- Tests added/updated
- Documentation updated
- No console.log or debug code
- Branch is up to date with main
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
## Screenshots (if applicable)
[Add screenshots]
## Checklist
- [ ] My code follows the style guidelines
- [ ] I have performed a self-review
- [ ] I have commented my code where necessary
- [ ] I have updated the documentation
- [ ] My changes generate no new warnings- Automated checks run on all PRs
- Code review by at least one maintainer
- Testing in staging environment
- Merge when approved and tests pass
// Good: Clear, typed, documented
interface IndicatorData {
id: string;
value: number;
status: 'green' | 'amber' | 'red';
}
/**
* Calculate the HOPI score based on indicator states
* @param indicators - Array of current indicator data
* @returns HOPI score between 0-100
*/
export function calculateHOPI(indicators: IndicatorData[]): number {
// Implementation
}
// Bad: Unclear, untyped, undocumented
function calc(data) {
// Mystery implementation
}# Good: Type hints, docstrings, clear naming
from typing import List, Dict, Optional
from datetime import datetime
def fetch_indicator_data(
indicator_id: str,
start_date: Optional[datetime] = None
) -> Dict[str, float]:
"""
Fetch indicator data from primary source.
Args:
indicator_id: Unique indicator identifier
start_date: Optional start date for historical data
Returns:
Dictionary of timestamp: value pairs
Raises:
DataSourceError: If source is unavailable
"""
# Implementation
# Bad: No types, no docs, unclear
def get_data(id, date=None):
# Implementation// Good: Typed props, memoization, clear structure
interface IndicatorCardProps {
indicator: IndicatorData;
onSelect?: (id: string) => void;
}
export const IndicatorCard: React.FC<IndicatorCardProps> = React.memo(({
indicator,
onSelect
}) => {
// Component implementation
});
// Bad: Untyped, not memoized
export function Card(props) {
// Component implementation
}- Use Tailwind utilities first
- Custom CSS only when necessary
- Follow dark theme color palette
- Ensure responsive design
// Frontend test example
describe('calculateHOPI', () => {
it('should return 0 for all green indicators', () => {
const indicators = [
{ id: '1', value: 1, status: 'green' },
{ id: '2', value: 1, status: 'green' }
];
expect(calculateHOPI(indicators)).toBe(0);
});
it('should weight critical indicators higher', () => {
// Test implementation
});
});# Backend test example
def test_treasury_collector():
"""Test treasury tail risk data collection."""
collector = TreasuryTailCollector()
# Mock the API response
with patch('requests.get') as mock_get:
mock_get.return_value.json.return_value = {
'value': 2.3
}
result = collector.collect()
assert result.value == 2.3
assert result.status == 'amber'Test complete workflows:
- User viewing dashboard
- Alert generation and delivery
- Data collection pipeline
- API endpoint responses
- Dashboard load time < 3s
- API response time < 200ms
- Memory usage stable over time
- Functions: Document parameters, returns, exceptions
- Complex logic: Add inline comments
- Components: Document props and usage
- APIs: Include example requests/responses
When adding features:
- Update user manual
- Add to FAQ if needed
- Include screenshots
- Update video tutorials list
For architectural changes:
- Update architecture diagram
- Document design decisions
- Update API documentation
- Add to changelog
- Discord: https://discord.gg/canairy
- GitHub Discussions: For questions and ideas
- Stack Overflow: Tag with
canairy
- Be respectful and inclusive
- Provide context in discussions
- Share knowledge and help others
- Celebrate contributions!
Contributors are recognized in:
- Release notes
- Contributors page
- Annual community report
Focus areas:
- Performance optimization
- Mobile responsiveness
- Accessibility (WCAG 2.1)
- New visualization types
- PWA enhancements
Focus areas:
- New data collectors
- API performance
- Caching strategies
- Database optimization
- Security hardening
Focus areas:
- Indicator correlation analysis
- Predictive modeling
- Anomaly detection
- Pattern matching algorithms
Focus areas:
- CI/CD improvements
- Monitoring/alerting
- Deployment automation
- Cost optimization
- Security scanning
Focus areas:
- Translations
- Video tutorials
- Use case examples
- API client libraries
- Integration guides
We follow semantic versioning:
- Patch (x.x.1): Bug fixes
- Minor (x.1.x): New features, backward compatible
- Major (1.x.x): Breaking changes
Releases happen:
- Patches: As needed
- Minor: Monthly
- Major: Quarterly
By contributing, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to Canairy! Together, we're building a more prepared and resilient world. 🐦
Questions? Reach out to contribute@canairy.app