Guidelines for contributing to the Shazan marketplace platform.
- Code of Conduct
- Getting Started
- Development Workflow
- Code Standards
- Testing
- Commit Guidelines
- Pull Request Process
- Reporting Issues
We are committed to providing a welcoming and inclusive environment for all contributors. We expect all participants to:
- Treat everyone with respect and kindness
- Welcome different perspectives and experiences
- Provide constructive feedback
- Focus on learning and improvement
The following behaviors are not tolerated:
- Harassment, discrimination, or intimidation
- Offensive language or personal attacks
- Publishing others' private information
- Any form of abuse or violence
Violations should be reported to the project maintainers. All complaints will be reviewed confidentially.
- Node.js (v16+)
- PostgreSQL (v12+)
- Git
- Code editor (VSCode recommended)
-
Fork the repository
git clone https://github.com/yourusername/shazan.git cd shazan -
Create a feature branch
git checkout -b feature/your-feature-name
-
Install dependencies
npm install
-
Setup environment variables
cp .env.example .env # Edit .env with your local configuration -
Initialize database
npx prisma migrate dev --name init
-
Start development server
npm run start:dev
Use descriptive branch names following this pattern:
feature/description # New feature
fix/description # Bug fix
refactor/description # Code refactoring
docs/description # Documentation
chore/description # Maintenance tasks
Examples:
feature/add-seller-verificationfix/payment-calculation-errorrefactor/auction-servicedocs/api-endpoints
-
Create and checkout feature branch
git checkout -b feature/your-feature
-
Make your changes
- Write code following project standards
- Add tests for new functionality
- Update documentation as needed
-
Run tests and linting
npm run test npm run lint npm run format -
Commit changes
git commit -m "feat: add seller verification endpoint" -
Push to your fork
git push origin feature/your-feature
-
Create Pull Request
- Go to repository on GitHub
- Click "New Pull Request"
- Select your branch and write a descriptive PR description
- Use TypeScript for all code (no JavaScript)
- Enable strict type checking:
"strict": true - Use meaningful variable and function names
- Avoid
anytypes - use proper typing
Example:
// Good
export async function getUserById(userId: string): Promise<UserDto> {
const user = await this.usersService.findById(userId);
return this.mapToDto(user);
}
// Avoid
export async function getUser(id: any): Promise<any> {
return this.service.get(id);
}src/
├── users/
│ ├── users.controller.ts
│ ├── users.service.ts
│ ├── users.module.ts
│ ├── dto/
│ │ ├── create-user.dto.ts
│ │ └── update-user.dto.ts
│ └── __tests__/
│ └── users.service.spec.ts
- Classes: PascalCase (UserService, CreateUserDto)
- Functions/Methods: camelCase (getUserById, createUser)
- Constants: UPPER_SNAKE_CASE (DATABASE_URL, MAX_RETRIES)
- Files: kebab-case (user.controller.ts, create-user.dto.ts)
- Interfaces: Prefix with I (IUserRepository)
/**
* Creates a new user account
*
* @param createUserDto - User creation data
* @returns Promise<UserDto> - Created user
* @throws ConflictException if email already exists
*
* @example
* await usersService.create({
* email: 'user@example.com',
* password: 'password'
* })
*/
export async function create(createUserDto: CreateUserDto): Promise<UserDto> {
// Implementation
}// Good - Use NestJS HttpException
throw new ConflictException('User with this email already exists');
throw new NotFoundException(`User with ID ${id} not found`);
throw new BadRequestException('Invalid email format');
// Avoid
throw new Error('Something went wrong');Use NestJS validation with DTOs:
import { IsEmail, IsString, MinLength } from 'class-validator';
export class CreateUserDto {
@IsEmail()
email: string;
@IsString()
@MinLength(8)
password: string;
@IsString()
firstName: string;
}// users.service.spec.ts
describe('UsersService', () => {
let service: UsersService;
let repository: Repository<User>;
beforeEach(async () => {
// Setup test module
});
describe('getUserById', () => {
it('should return user when found', async () => {
// Arrange
const userId = 'test-id';
const expectedUser = { id: userId, email: 'test@example.com' };
// Act
const result = await service.getUserById(userId);
// Assert
expect(result).toEqual(expectedUser);
});
it('should throw NotFoundException when user not found', async () => {
// Arrange
const userId = 'non-existent-id';
// Act & Assert
await expect(service.getUserById(userId))
.rejects
.toThrow(NotFoundException);
});
});
});# Run all tests
npm run test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:cov- Minimum: 80% overall coverage
- Services: 90% coverage (critical business logic)
- Controllers: 70% coverage (HTTP handling)
- Utils: 95% coverage (common utilities)
<type>(<scope>): <subject>
<body>
<footer>
feat- New featurefix- Bug fixdocs- Documentation changesstyle- Code style changes (formatting, semicolons, etc)refactor- Code refactoring without feature changeperf- Performance improvementtest- Test additions/changeschore- Build/dependency changes
- Use imperative mood ("add" not "added")
- Start with lowercase
- No period at the end
- Maximum 50 characters
- Explain WHAT and WHY, not HOW
- Wrap at 72 characters
- Separate from subject with blank line
Good Commits:
feat(auth): add email verification endpoint
Implement OTP verification for user email confirmation
during signup process. Reduces spam and improves
account security.
Closes #123
fix(payments): correct fee calculation for decimal amounts
Round decimal amounts properly before calculating
platform fee. Prevents rounding errors that caused
incorrect seller payouts.
Fixes #456
Avoid:
fixed stuff
WIP
update
did some changes
-
Update your branch
git fetch origin git rebase origin/main
-
Run all checks locally
npm run lint npm run format npm run test npm run build -
Update documentation
- Update API.md if endpoints changed
- Update README.md for new features
- Add comments for complex logic
## Description
Brief description of changes
## Type of Change
- [ ] New feature
- [ ] Bug fix
- [ ] Breaking change
- [ ] Documentation update
## Related Issues
Closes #123
## Testing
Describe how to test these changes
## Checklist
- [ ] Code follows style guidelines
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] No console.log or debug code
- [ ] All tests pass locally- Provide constructive feedback
- Suggest improvements politely
- Ask questions if unclear
- Approve when satisfied
- Request changes if issues found
- Address any remaining comments
- Re-request review after updates
- Squash commits if requested
- Merge after final approval
## Description
Clear description of the issue
## Steps to Reproduce
1. Step one
2. Step two
3. Step three
## Expected Behavior
What should happen
## Actual Behavior
What actually happens
## Environment
- OS: [e.g. macOS 12.1]
- Node: [e.g. 16.13.0]
- Database: [e.g. PostgreSQL 13]
## Screenshots
If applicable, add screenshots
## Additional Context
Any other relevant information- Critical: System down, data loss, security issue
- High: Major feature broken, significant impact
- Medium: Standard bug or feature request
- Low: Minor issue, nice to have
// Good - Use select to limit fields
const users = await prisma.auth.findMany({
select: { id: true, email: true, firstName: true },
where: { role: 'SELLER' }
});
// Avoid - SELECT *
const users = await prisma.auth.findMany({
where: { role: 'SELLER' }
});- Cache frequently accessed data
- Invalidate cache on updates
- Use Redis for performance-critical data
// Good - Use include
const ads = await prisma.ad.findMany({
include: {
seller: true,
images: true
}
});
// Avoid - Querying in loop
for (const ad of ads) {
const seller = await prisma.auth.findUnique({
where: { id: ad.sellerId }
});
}Always validate user input:
// Use class-validator decorators
export class CreateAdDto {
@IsString()
@MinLength(5)
@MaxLength(200)
title: string;
@IsNumber()
@Min(0)
price: number;
}- Use Prisma (protection built-in)
- Never concatenate queries
- Always use parameterized queries
- Always validate JWT tokens
- Use @UseGuards(AuthGuard) on protected endpoints
- Never store passwords in plain text
- Implement rate limiting on public endpoints
- Use stricter limits for authentication endpoints
Should include:
- Project description
- Tech stack
- Setup instructions
- Running tests
- Contributing guidelines
Should document:
- All endpoints
- Request/response formats
- Error codes
- Authentication requirements
- Example usage
// Good - Explain complex logic
// Filter sellers with active listings and high ratings
// to ensure quality results for customers
const topSellers = sellers.filter(seller =>
seller.activeListings > 0 && seller.rating >= 4.5
);
// Avoid - Obvious comments
// Loop through users
for (const user of users) {- Questions: Open a Discussion on GitHub
- Bugs: Open an Issue with details
- Features: Discuss in Issues before submitting PR
- Documentation: Check existing docs first
By contributing, you agree that your contributions will be licensed under the project's license.
Thank you for contributing to Shazan!