Thank you for your interest in contributing to the Nanle News Aggregator! This document provides guidelines and information for contributors.
- Getting Started
- Development Setup
- Code Standards
- Testing
- Pull Request Process
- Issue Reporting
- Code of Conduct
- Docker Desktop - For containerized development
- Git - For version control
- Code Editor - VS Code, PhpStorm, or similar
- API Keys - For news services (optional for development)
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/nanle-home-task.git cd nanle-home-task - Add upstream remote:
git remote add upstream https://github.com/ORIGINAL_OWNER/nanle-home-task.git
# Build and start all services
make build
make up
# Check status
make status
# View logs
make logs-
Create a feature branch:
git checkout -b feature/your-feature-name
-
Make your changes and test locally
-
Commit your changes:
git add . git commit -m "feat: add new feature description"
-
Push to your fork:
git push origin feature/your-feature-name
-
Create a Pull Request on GitHub
# Backend development
make shell-backend # Access backend container
make artisan cmd="migrate" # Run Laravel commands
make test # Run backend tests
# Frontend development
make shell-frontend # Access frontend container
make npm-install # Install dependencies
make test-frontend # Run frontend tests
# Database operations
make migrate-fresh # Reset database with seeding
make shell-db # Access database shell
make db-backup # Create database backup
# Monitoring
make status # Check service status
make health # Health check endpoints
make logs-backend # View backend logs- Follow PSR-12 coding standards
- Use Laravel conventions for naming and structure
- Write meaningful commit messages using conventional commits
// ✅ Good
class ArticleController extends Controller
{
public function index(Request $request): JsonResponse
{
$articles = Article::with(['source', 'category'])
->filter($request->all())
->paginate(20);
return response()->json($articles);
}
}
// ❌ Avoid
class articlecontroller extends controller
{
public function index($request)
{
$articles = Article::all();
return $articles;
}
}backend/
├── app/
│ ├── Http/Controllers/ # API controllers
│ ├── Models/ # Eloquent models
│ ├── Services/ # Business logic
│ └── Console/Commands/ # Artisan commands
├── routes/
│ └── api.php # API routes
├── database/
│ ├── migrations/ # Database migrations
│ └── seeders/ # Database seeders
└── tests/ # PHPUnit tests
- Use TypeScript for all new code
- Follow React best practices
- Use functional components with hooks
- Implement proper error handling
// ✅ Good
interface ArticleProps {
article: Article;
onBookmark: (id: number) => void;
}
export const ArticleCard: React.FC<ArticleProps> = ({
article,
onBookmark
}) => {
const handleBookmark = useCallback(() => {
onBookmark(article.id);
}, [article.id, onBookmark]);
return (
<div className="article-card">
<h3>{article.title}</h3>
<button onClick={handleBookmark}>
Bookmark
</button>
</div>
);
};
// ❌ Avoid
export function ArticleCard(props: any) {
return <div>{props.article.title}</div>;
}frontend/src/
├── components/ # Reusable components
├── pages/ # Page components
├── hooks/ # Custom hooks
├── services/ # API services
├── store/ # Redux store
├── types/ # TypeScript types
└── utils/ # Utility functions
Use conventional commits format:
# Format: type(scope): description
feat(auth): add email verification
fix(articles): resolve pagination issue
docs(readme): update installation instructions
style(components): improve button styling
refactor(api): simplify article filtering
test(auth): add login test cases
chore(deps): update dependencies# Run all tests
make test
# Run specific test file
make artisan cmd="test --filter=ArticleTest"
# Run with coverage
make artisan cmd="test --coverage"// tests/Feature/ArticleTest.php
class ArticleTest extends TestCase
{
use RefreshDatabase;
public function test_can_fetch_articles(): void
{
$response = $this->getJson('/api/articles');
$response->assertStatus(200)
->assertJsonStructure([
'data' => [
'*' => ['id', 'title', 'content']
]
]);
}
}# Run all tests
make test-frontend
# Run tests in watch mode
make shell-frontend
yarn test --watch// src/components/__tests__/ArticleCard.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { ArticleCard } from '../ArticleCard';
describe('ArticleCard', () => {
it('renders article title', () => {
const article = { id: 1, title: 'Test Article' };
render(<ArticleCard article={article} onBookmark={jest.fn()} />);
expect(screen.getByText('Test Article')).toBeInTheDocument();
});
});-
Ensure tests pass:
make test make test-frontend -
Check code style:
# Backend make shell-backend composer lint # Frontend make shell-frontend yarn lint
-
Update documentation if needed
-
Test your changes thoroughly
- Use descriptive titles and descriptions
- Reference issues using
#issue-number - Include screenshots for UI changes
- Describe testing steps for reviewers
- Keep PRs focused - one feature per PR
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Backend tests pass
- [ ] Frontend tests pass
- [ ] Manual testing completed
## Screenshots (if applicable)
Add screenshots for UI changes
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] Tests added/updated- Search existing issues to avoid duplicates
- Check documentation and troubleshooting guides
- Try to reproduce the issue locally
## Bug Description
Clear description of the issue
## Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. See error
## Expected Behavior
What should happen
## Actual Behavior
What actually happens
## Environment
- OS: [e.g., macOS, Windows, Linux]
- Browser: [e.g., Chrome, Firefox, Safari]
- Version: [e.g., 1.0.0]
## Additional Information
Screenshots, logs, or other relevant information- Address review comments promptly
- Request re-review when changes are made
- Be open to feedback and suggestions
- Be constructive and respectful
- Focus on code quality and functionality
- Provide specific feedback with examples
- Approve when satisfied with changes
- Be respectful and inclusive
- Use welcoming language
- Be collaborative and open to feedback
- Focus on constructive criticism
- Harassment or discrimination
- Trolling or insulting comments
- Publishing private information
- Unprofessional conduct
- Documentation: Check the README.md
- API Docs: http://localhost:8000/docs (when running)
- Issues: Search existing issues on GitHub
- Discussions: Use GitHub Discussions for questions
- Issues: Create an issue on GitHub
- Security: Report security issues privately
- Questions: Use GitHub Discussions
Thank you for contributing to Nanle News Aggregator! 🎉