This guide covers the development workflow and contribution process for OpenJustice.
- Getting Started
- Development Workflow
- Git Workflow
- Pull Request Process
- Code Review Guidelines
- Commit Message Conventions
- Branch Naming
- Best Practices
Before contributing, ensure you have:
- Node.js 18+ installed
- PostgreSQL 15+ installed and running
- Git 2.30+ installed
- Familiarity with TypeScript, NestJS, and Prisma
- Fork the repository on GitHub
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/openjustice.git
cd openjustice- Add upstream remote:
git remote add upstream https://github.com/ORIGINAL_OWNER/openjustice.git
git remote -v# Backend setup
cd openjustice-server
npm install
cp .env.example .env
# Edit .env with your database credentials
# Run migrations
npx prisma generate
npx prisma db push
npx prisma db seed
# Start development server
npm run start:dev
# Frontend setup (in new terminal)
cd ../openjustice-client
npm install
cp .env.example .env.local
npm run devBefore starting work:
- Search existing issues: https://github.com/OWNER/openjustice/issues
- Comment on the issue to claim it
- If no issue exists, create one describing your proposed changes
Keep your fork up to date:
# Fetch upstream changes
git fetch upstream
# Merge upstream main into your local main
git checkout main
git merge upstream/main
# Push to your fork
git push origin main# Create and switch to a new branch
git checkout -b feat/your-feature-name
# Examples:
git checkout -b feat/add-vehicle-search
git checkout -b fix/case-number-generation
git checkout -b docs/update-api-referenceFollow our coding standards:
- Read Code Style Guide
- Write tests for new features
- Update documentation
- Follow project structure patterns
# Run linter
npm run lint
# Run tests
npm test
# Run E2E tests
npm run test:e2e
# Build to catch compilation errors
npm run buildFollow our commit message conventions:
# Stage changes
git add .
# Commit with descriptive message
git commit -m "feat(vehicles): add search by registration number"git push origin feat/your-feature-name- Go to your fork on GitHub
- Click "New Pull Request"
- Select base:
main← compare:feat/your-feature-name - Fill out the PR template
- Submit the pull request
We use GitHub Flow (simplified Git Flow):
main (production-ready)
↑
feat/feature-name
fix/bug-name
docs/documentation-update
refactor/code-improvement
Key points:
mainis always deployable- Feature branches are short-lived
- All changes go through pull requests
- No direct commits to
main
| Prefix | Purpose | Example |
|---|---|---|
feat/ |
New features | feat/add-vehicle-module |
fix/ |
Bug fixes | fix/case-status-transition |
docs/ |
Documentation | docs/update-api-guide |
refactor/ |
Code refactoring | refactor/extract-validation |
test/ |
Test additions/updates | test/add-vehicle-service-tests |
chore/ |
Maintenance tasks | chore/update-dependencies |
# Switch to your branch
git checkout feat/your-feature
# Make changes and commit
git add .
git commit -m "feat: implement feature X"
# Keep branch updated with main
git fetch upstream
git rebase upstream/main
# Push to your fork (use --force-with-lease after rebase)
git push origin feat/your-feature --force-with-leaseUse rebase to keep history clean:
# Update your branch with latest main
git checkout feat/your-feature
git fetch upstream
git rebase upstream/main
# Resolve conflicts if any
# Then continue
git rebase --continue
# Force push (with safety check)
git push origin feat/your-feature --force-with-leaseNever rebase branches others are working on!
Checklist:
- Code follows style guidelines
- Tests pass:
npm test - Build succeeds:
npm run build - Linter passes:
npm run lint - Documentation is updated
- Commit messages follow conventions
- Branch is up to date with main
Follow commit message format:
<type>(<scope>): <description>
Examples:
feat(vehicles): add vehicle search endpoint
fix(cases): resolve case number duplicate issue
docs(api): update vehicle API documentation
## Description
Brief description of changes made.
## Motivation and Context
Why is this change required? What problem does it solve?
## Type of Change
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## How Has This Been Tested?
Describe the tests you ran to verify your changes.
- [ ] Unit tests
- [ ] Integration tests
- [ ] E2E tests
- [ ] Manual testing
## Checklist
- [ ] My code follows the code style of this project
- [ ] I have updated the documentation accordingly
- [ ] I have added tests to cover my changes
- [ ] All new and existing tests pass
- [ ] My changes generate no new warnings
- [ ] I have checked my code and corrected any misspellings
## Screenshots (if applicable)
Add screenshots to help explain your changes.
## Related Issues
Closes #123
Related to #456Keep PRs small and focused:
- Small: < 200 lines changed ✅ Ideal
- Medium: 200-500 lines
⚠️ Acceptable - Large: > 500 lines ❌ Split into smaller PRs
Large PRs take longer to review and are more likely to have issues.
Use draft PRs for work in progress:
# Create draft PR on GitHub
gh pr create --draft --title "WIP: Add vehicle search" --body "Work in progress"
# Convert to ready for review when done
gh pr readyResponding to feedback:
- Be open to feedback and constructive criticism
- Respond promptly to review comments
- Make requested changes or explain why not
- Re-request review after making changes
- Thank reviewers for their time
Making changes:
# Make requested changes
git add .
git commit -m "fix: address review feedback"
# Push to update PR
git push origin feat/your-featureWhat to look for:
-
Correctness
- Does the code do what it's supposed to?
- Are there any logical errors?
- Are edge cases handled?
-
Code Quality
- Follows style guidelines?
- Proper error handling?
- Adequate test coverage?
- Clear and maintainable?
-
Architecture
- Follows established patterns?
- Proper separation of concerns?
- No unnecessary dependencies?
-
Security
- No security vulnerabilities?
- Input validation present?
- No exposed secrets?
-
Performance
- Efficient algorithms?
- Proper database indexing?
- No N+1 queries?
-
Documentation
- Code is self-documenting?
- Complex logic is commented?
- API documentation updated?
Review comments:
- Be constructive and respectful
- Explain the "why" behind suggestions
- Use conventional comment prefixes:
nit:Minor suggestion (non-blocking)question:Seeking clarificationsuggestion:Proposal for improvementissue:Problem that must be addressed
Example comments:
✅ Good:
"nit: Consider extracting this validation into a separate method for reusability."
"question: Should we handle the case where officerId is null?"
"suggestion: We could use a transaction here to ensure data consistency."
❌ Bad:
"This is wrong."
"Why did you do it this way?"
"Rewrite this."
Requirements for merge:
- At least 1 approval from maintainers
- All CI checks passing
- No merge conflicts
- Branch up to date with main
Maintainer responsibilities:
- Review PRs within 2 business days
- Provide clear, actionable feedback
- Merge approved PRs promptly
We follow Conventional Commits specification.
<type>(<scope>): <subject>
[optional body]
[optional footer]
| Type | Description | Example |
|---|---|---|
feat |
New feature | feat(vehicles): add search endpoint |
fix |
Bug fix | fix(cases): resolve status transition bug |
docs |
Documentation | docs(api): update authentication guide |
style |
Code style (no logic change) | style: format code with Prettier |
refactor |
Code refactoring | refactor(auth): extract JWT validation |
test |
Adding/updating tests | test(vehicles): add unit tests |
chore |
Maintenance | chore: update dependencies |
perf |
Performance improvement | perf(cases): optimize query |
ci |
CI/CD changes | ci: add GitHub Actions workflow |
build |
Build system changes | build: update webpack config |
revert |
Revert previous commit | revert: feat(vehicles): add search |
Scope represents the module affected:
vehiclescasespersonsauthevidenceapidbdeps
- Use imperative mood: "add" not "added" or "adds"
- Don't capitalize first letter
- No period at the end
- Limit to 50 characters
- Explain what and why, not how
- Wrap at 72 characters
- Separate from subject with blank line
- Reference issues:
Closes #123,Fixes #456 - Note breaking changes:
BREAKING CHANGE: description
Simple commit:
feat(vehicles): add vehicle search by registration
With body:
feat(vehicles): add vehicle search by registration
Implements fuzzy search to help officers find vehicles even with
partial or slightly incorrect registration numbers.
Closes #123
Breaking change:
feat(api): change vehicle response format
BREAKING CHANGE: Vehicle API now returns owner object instead of ownerId.
Update client code to use vehicle.owner.id instead of vehicle.ownerId.
Bug fix:
fix(cases): resolve case number generation race condition
Add database-level sequence to prevent duplicate case numbers when
multiple officers create cases simultaneously.
Fixes #456
✅ Do:
- Write self-documenting code
- Add tests for all new features
- Keep functions small and focused
- Handle errors appropriately
- Log important operations
- Validate all inputs
❌ Don't:
- Skip writing tests
- Commit commented-out code
- Leave TODO comments without issues
- Commit console.log statements
- Commit secrets or credentials
- Make unrelated changes in one PR
✅ Do:
- Write unit tests for services
- Write integration tests for repositories
- Write E2E tests for critical flows
- Test error conditions
- Mock external dependencies
- Aim for >80% code coverage
❌ Don't:
- Skip testing error cases
- Use real databases in unit tests
- Write flaky tests
- Test implementation details
✅ Do:
- Update API documentation
- Add JSDoc for public APIs
- Update README if needed
- Document breaking changes
- Include code examples
❌ Don't:
- Leave outdated documentation
- Assume code is self-explanatory
- Forget to document limitations
✅ Do:
- Make atomic commits (one logical change per commit)
- Write clear commit messages
- Keep branches up to date
- Delete merged branches
- Use meaningful branch names
❌ Don't:
- Make massive commits
- Use generic messages ("fix", "update")
- Commit directly to main
- Leave stale branches
If you need assistance:
- Documentation: Check the docs
- Issues: Search existing issues for similar questions
- Discussions: Use GitHub Discussions for questions
- Discord/Slack: Join our community chat (if available)
Contributors will be:
- Listed in CONTRIBUTORS.md
- Mentioned in release notes
- Credited in documentation
Thank you for contributing to OpenJustice!
- Project Structure - Understand the codebase
- Creating Modules - Add new features
- Code Style - Follow conventions
- Testing - Write quality tests