Contributing to ziegel ​
We love your input! We want to make contributing to ziegel as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer
Development Process ​
We use GitHub to host code, to track issues and feature requests, as well as accept pull requests.
Pull Requests ​
Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests:
- Fork the repo and create your branch from
main - If you've added code that should be tested, add tests
- If you've changed APIs, update the documentation
- Ensure the test suite passes
- Make sure your code lints
- Issue that pull request!
Development Setup ​
Prerequisites ​
- Node.js 18 or higher
- Yarn package manager
- Git
Getting Started ​
Clone the repository
bashgit clone https://github.com/RueDeRennes/ziegel cd ziegelInstall dependencies
bashyarn installVerify the setup
bash# Run tests yarn test # Build all packages yarn build # Run linting yarn lint
Project Structure ​
ziegel/
├── libs/ # All library packages
│ ├── ziegel-core/ # Core utilities and foundation
│ ├── ziegel-platform/ # Platform services
│ ├── ziegel-platform-http/ # HTTP client implementation
│ ├── ziegel-data/ # Data access patterns
│ ├── ziegel-intl/ # Internationalization
│ └── ... # Other packages
├── apps/
│ └── ziegel-docs/ # Documentation website
├── .docs/ # Generated API documentation
├── package.json # Root package configuration
├── nx.json # Nx workspace configuration
└── tsconfig.json # TypeScript configurationWorking with the Monorepo ​
This project uses Nx for monorepo management:
# Build a specific package
nx build ziegel-core
# Test a specific package
nx test ziegel-platform-http
# Build all packages
nx run-many --target=build --all
# Test all packages
nx run-many --target=test --all
# Generate dependency graph
nx graphPackage Development ​
Each package follows a consistent structure:
libs/package-name/
├── src/ # Source code
│ ├── Index.ts # Main export file
│ └── ... # Package modules
├── tests/ # Test files
├── package.json # Package configuration
├── project.json # Nx project configuration
├── tsconfig.json # TypeScript configuration
├── README.md # Package documentation
└── api-extractor.json # API documentation configDevelopment Guidelines ​
Code Style ​
We use ESLint and Prettier to maintain consistent code style:
# Check linting
yarn lint
# Fix linting issues
yarn lint:fix
# Format code
yarn formatTypeScript Guidelines ​
- Use strict TypeScript settings
- Prefer interfaces over type aliases for object types
- Use explicit return types for public APIs
- Document public APIs with JSDoc comments
/**
* Calculates the distance between two points.
*
* @param point1 - The first point
* @param point2 - The second point
* @returns The distance between the points
*
* @public
*/
export function calculateDistance(point1: Point, point2: Point): number {
// Implementation
}Naming Conventions ​
- Classes: PascalCase (
UserService,HttpClient) - Interfaces: PascalCase with 'I' prefix (
IUserRepository,ILogger) - Methods/Functions: camelCase (
getUserById,processData) - Variables: camelCase (
userName,isActive) - Constants: UPPER_SNAKE_CASE (
MAX_RETRIES,DEFAULT_TIMEOUT) - Files: PascalCase for classes, camelCase for others
Testing ​
We use Vitest for testing. All new code should include appropriate tests:
# Run all tests
yarn test
# Run tests for specific package
nx test ziegel-core
# Run tests in watch mode
yarn test:watch
# Generate coverage report
yarn test:coverageTest Structure ​
import { describe, it, expect, beforeEach } from 'vitest';
import { UserService } from '../src/UserService';
describe('UserService', () => {
let userService: UserService;
beforeEach(() => {
userService = new UserService();
});
describe('getUser', () => {
it('should return user when valid id provided', async () => {
// Arrange
const userId = '123';
// Act
const result = await userService.getUser(userId);
// Assert
expect(result).toBeDefined();
expect(result.id).toBe(userId);
});
it('should throw error when user not found', async () => {
// Arrange
const invalidId = 'invalid';
// Act & Assert
await expect(userService.getUser(invalidId))
.rejects.toThrow('User not found');
});
});
});Test Coverage ​
- Aim for at least 80% code coverage
- Focus on testing public APIs and critical business logic
- Use meaningful test descriptions
- Group related tests using
describeblocks
Documentation ​
API Documentation ​
Public APIs must be documented using JSDoc:
/**
* Represents a user in the system.
*
* @public
*/
export interface IUser {
/**
* The unique identifier for the user.
*/
id: string;
/**
* The user's display name.
*/
name: string;
/**
* The user's email address.
*/
email: string;
}
/**
* Service for managing user operations.
*
* @public
*/
export class UserService {
/**
* Retrieves a user by their ID.
*
* @param id - The user's unique identifier
* @returns A promise that resolves to the user
* @throws {@link NotFoundException} When the user is not found
*
* @example
* ```typescript
* const userService = new UserService();
* const user = await userService.getUser('123');
* console.log(user.name);
* ```
*/
async getUser(id: string): Promise<IUser> {
// Implementation
}
}README Files ​
Each package should have a comprehensive README including:
- Package description and purpose
- Installation instructions
- Basic usage examples
- API overview
- Links to detailed documentation
Examples ​
Include practical examples that demonstrate real-world usage:
// Basic usage
import { HttpClient } from '@breadstone/ziegel-platform-http';
const client = new HttpClient({
baseUrl: 'https://api.example.com'
});
const users = await client.get<User[]>('/users');Performance Considerations ​
- Avoid memory leaks by properly disposing resources
- Use lazy loading for expensive operations
- Implement proper caching strategies
- Consider bundle size impact for client-side usage
// Good: Lazy initialization
class ExpensiveService {
private _resource: Lazy<HeavyResource> = new Lazy(() => new HeavyResource());
get resource(): HeavyResource {
return this._resource.value;
}
}
// Good: Proper resource disposal
using connection = await database.connect();
const results = await connection.query('SELECT * FROM users');
// connection automatically disposedError Handling ​
Use structured error handling with meaningful error messages:
import { ArgumentException, NotFoundException } from '@breadstone/ziegel-core';
export class UserService {
async getUser(id: string): Promise<User> {
if (!id) {
throw new ArgumentException('User ID is required', 'id');
}
const user = await this.repository.findById(id);
if (!user) {
throw new NotFoundException(`User with ID '${id}' not found`);
}
return user;
}
}Commit Message Guidelines ​
We follow Conventional Commits specification:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]Types ​
- feat: A new feature
- fix: A bug fix
- docs: Documentation only changes
- style: Changes that do not affect the meaning of the code
- refactor: A code change that neither fixes a bug nor adds a feature
- perf: A code change that improves performance
- test: Adding missing tests or correcting existing tests
- chore: Changes to the build process or auxiliary tools
Examples ​
feat(http): add request retry mechanism
fix(core): resolve memory leak in event handling
docs(platform): update configuration examples
test(data): add integration tests for repositoryRelease Process ​
Version Management ​
We use semantic versioning (SemVer):
- MAJOR: Incompatible API changes
- MINOR: Backward-compatible functionality additions
- PATCH: Backward-compatible bug fixes
Release Workflow ​
Create Release Branch
bashgit checkout -b release/v1.2.0Update Version Numbers
bashnx release version 1.2.0Generate Changelog
bashnx release changelogBuild and Test
bashyarn build yarn testCreate Pull Request
- Target:
mainbranch - Include changelog updates
- Wait for review and approval
- Target:
Publish Release
bashnx release publish
Issue Reporting ​
Bug Reports ​
When filing a bug report, please include:
Environment Information
- Node.js version
- Package versions
- Operating system
Steps to Reproduce
- Clear, numbered steps
- Minimal code example
- Expected vs actual behavior
Additional Context
- Screenshots (if applicable)
- Error messages
- Related issues
Feature Requests ​
For feature requests, please provide:
Problem Description
- What problem does this solve?
- Who would benefit from this feature?
Proposed Solution
- Detailed description of the feature
- API design (if applicable)
- Examples of usage
Alternatives Considered
- Other approaches you've considered
- Why this approach is preferred
Community Guidelines ​
Code of Conduct ​
This project adheres to a code of conduct. By participating, you are expected to uphold this code:
- Be respectful and inclusive
- Provide constructive feedback
- Focus on what is best for the community
- Show empathy towards other community members
Getting Help ​
- Documentation: Check the documentation website
- Issues: Search existing issues before creating new ones
- Discussions: Use GitHub Discussions for questions and ideas
Security ​
Reporting Security Issues ​
Please do not report security vulnerabilities through public GitHub issues. Instead:
- Email security concerns to: awehlert@breadstone.de
- Include detailed information about the vulnerability
- Allow time for investigation and resolution before disclosure
Security Best Practices ​
- Keep dependencies up to date
- Follow secure coding practices
- Validate all inputs
- Use proper authentication and authorization
License ​
By contributing to ziegel, you agree that your contributions will be licensed under the MIT License.
Recognition ​
Contributors will be recognized in:
- CHANGELOG.md for each release
- README.md contributors section
- Annual contributor highlights
Thank you for contributing to ziegel! 🎉