Thanks for your interest in contributing! This guide covers everything you need to get started.
- Getting Started
- Commit Message Convention
- Branch Naming
- Issue & PR Templates
- Pull Request Process
- Code Style
- Error Handling & Logging
- Running Tests
- Translations
-
Fork the repository and clone your fork:
git clone https://github.com/<your-username>/Blue-Collar.git cd Blue-Collar pnpm install
-
Install git hooks (runs automatically on
pnpm install, but run manually if needed):pnpm prepare
-
Create a feature branch (see Branch Naming).
-
Make your changes, commit using the convention below, and open a PR.
This project uses Conventional Commits to power automated changelog generation via release-please.
<type>(<scope>): <short description>
[optional body]
[optional footer(s)]
| Type | When to use |
|---|---|
feat |
A new feature |
fix |
A bug fix |
docs |
Documentation changes only |
i18n |
Translations and localization |
refactor |
Code change that neither fixes a bug nor adds a feature |
test |
Adding or updating tests |
chore |
Build process, dependency updates, tooling |
ci |
CI/CD configuration changes |
perf |
Performance improvements |
api, app, contracts, deps, ci, docs, sdk, types, monitoring, mobile
This project uses commitlint to enforce the conventional commit format on every commit. The git hook is managed by husky.
- Local hook: A
commit-msghook is installed viapnpm prepare(runs automatically afterpnpm install). It validates every commit message against the rules incommitlint.config.jsbefore allowing the commit. - Manual check: Run
pnpm commitlintto validate the last commit message, ornpx commitlint --edit <file>to validate a specific message file. - CI: The
Commit Lintworkflow re-checks every commit in a pull request, so messages that bypass the local hook (--no-verify, commits made in the GitHub web UI, or a clone wherepnpm installwas never run) still fail the PR. It is a required check, not advisory. - PR title: Pull requests are squash merged, so the PR title becomes the commit subject on
main. It is linted by the same rules and must follow the convention too.
If a commit is rejected with a commitlint error, fix the message and re-commit:
git commit --amend -m "feat(sdk): description that follows the convention"feat(api): add Google OAuth 2.0 login
fix(api): return 409 on duplicate email registration
docs(contracts): add full interface documentation
chore(deps): bump prisma to 7.2.0
test(api): add edge cases for worker toggle endpoint
refactor(api): extract payment logic into service layer
ci: add release-please workflow
Append ! after the type/scope, or add BREAKING CHANGE: in the footer:
feat(api)!: rename /workers/mine to /workers/curator
BREAKING CHANGE: clients must update the endpoint path.
This repository uses release-please to generate CHANGELOG.md from Conventional Commits.
Do not edit CHANGELOG.md manually; use the commit convention above and let the release workflow update the changelog on merge.
<type>/<short-description>
Examples:
feat/google-oauthfix/worker-toggle-authdocs/contracts-readmechore/bump-prisma
This repository provides structured templates for issues and pull requests:
| Template | File | When to Use |
|---|---|---|
| Bug Report | .github/ISSUE_TEMPLATE/bug_report.yml |
Reporting a bug |
| Feature Request | .github/ISSUE_TEMPLATE/feature_request.yml |
Suggesting a new feature |
| Documentation | .github/ISSUE_TEMPLATE/documentation.yml |
Documentation issues or improvements |
| Pull Request | .github/pull_request_template.md |
Opening a new PR |
Fill in all relevant sections. The templates include checklists specific to the type of change so reviewers can verify compliance quickly.
- Ensure all CI checks pass (
pnpm test,pnpm build,cargo clippy). - Write a clear PR title following the commit convention (release-please uses it).
- Reference the related issue:
Closes #123. - Request a review from a maintainer.
- Squash-merge is preferred to keep history clean.
- 2-space indent, double quotes
- Run
pnpm buildto catch type errors before pushing - Run
pnpm testto ensure no regressions - All input validation schemas live in
src/validations/. Do not create a separatevalidators/directory — add new Zod schemas as a file there and re-export them fromsrc/validations/index.ts.
- Run
make fmtbefore committing - Run
make clippy— zero warnings policy
See packages/app/CONTRIBUTING.md for frontend-specific conventions.
Both packages follow a single written standard: docs/ERROR_HANDLING_AND_LOGGING.md. Read it before adding an error path or a log line. In short:
- API: throw
AppErrorwith an explicitErrorCodeand let the globalerrorHandlerformat the response. Do not add newtry/catchblocks in controllers that build their own JSON, and do not add new callers ofhandleErrororsendError— both droperrorCodeandtraceId. - API logging: use
createServiceLogger(name)fromutils/logger.js. Pass structured fields as the first argument and the message as the second. Noconsole.*in application code. 4xx logs atwarnor below; only 5xx logs aterror. - Correlation IDs: the OpenTelemetry trace ID is the correlation ID. Read it with
getTraceId(); never invent a per-request UUID. Work that leaves the request context (queues, workers) must carrytraceIdin its payload. - App: render
parseApiError(err).messagefromlib/errors.ts— never a raw thrown message — and branch oncode/retryable, not on message text. - Never log PII: no bodies, headers, tokens, emails, or IP addresses.
The document ends with a review checklist;
reviewers are expected to use it. packages/api/src/__tests__/error-logging-conventions.test.ts
fails the build if the document and the code disagree.
When modifying the database schema:
- Make schema changes in
packages/api/prisma/schema.prisma - Create a migration:
npx prisma migrate dev --name <descriptive-name> - For destructive migrations (DROP COLUMN, DROP TABLE, ALTER COLUMN):
- Add the
migration:destructivelabel to your PR - Request explicit review from a maintainer
- Include justification in the PR description
- Add the
- CI will verify that destructive migrations are properly labeled
The CI pipeline will flag any migration containing:
DROP COLUMNDROP TABLEALTER COLUMN
These changes require the migration:destructive label and manual approval before merging.
# API tests
cd packages/api
pnpm test
# Contract tests
cd packages/contracts
cargo test
# App
cd packages/app
pnpm testSee docs/i18n-translations.md for contributing translations to the app UI and README files. This includes:
- Adding a new language to the Next.js frontend (message JSON files)
- Translating README files to new languages
- Keeping translations in sync with the English source
- Validating translation completeness
Translation PRs should use the i18n: commit type and reference the language being added.