Thanks for contributing to Useroutr. This document defines the expected workflow, quality bar, and review checklist for all changes.
Useroutr is payment infrastructure. Favor correctness and safety over speed:
- Keep changes small and focused.
- Preserve non-custodial and atomic-settlement assumptions.
- Do not ship incomplete money-flow logic behind unclear behavior.
- Avoid unrelated refactors in the same PR.
apps/api— NestJS backend modules (auth, quotes, payments, relay, bridge, etc.)packages/types— shared types/schemas used across servicespackages/stellar— Stellar client wrapperscontract/soroban— Rust Soroban contractscontract/evm— Solidity HTLC contracts and Hardhat configcontract/starknet— Cairo HTLC contract
- Install dependencies from repo root:
npm install- Copy environment file:
cp .env.example .env- Start local infrastructure:
docker compose up -d- Update
.envDB URL for local Docker mapping (5434):
DATABASE_URL="postgresql://useroutr:password@localhost:5434/useroutr"- Run Prisma migration/generate from
apps/api:
cd apps/api
npx prisma migrate dev
npx prisma generate- Start API dev server:
npm run start:dev- Create a feature branch from
main. - Use clear branch names:
feat/<short-description>fix/<short-description>chore/<short-description>
- Open one PR per logical change.
- Include implementation notes + test evidence in PR description.
Use clear, imperative commit messages:
feat(quotes): add redis quote lock validationfix(relay): handle missing stellar lock idtest(payments): cover completed -> refunded timeout path
Keep commits atomic; avoid mixing generated noise with logic changes where possible.
- Follow existing module boundaries.
- Validate input at API boundaries.
- Keep business logic in services; controllers should stay thin.
- Reuse shared types from
packages/typeswhen possible. - Do not hardcode secrets or chain credentials.
- Treat any contract change as high-risk.
- Add or update tests for all state transition changes.
- Document security assumptions and timeout semantics in PR.
- Never remove safety checks (timelock, hashlock, authorization) without explicit design approval.
Before opening a PR, run relevant tests for touched areas.
npm run test
npm run test:e2e
npm run buildcargo testnpm install
npx hardhat testIf a test is skipped, explain why in the PR description.
- Schema changes must include a Prisma migration.
- Keep migration names descriptive.
- Avoid force-resetting shared databases.
- Verify backward compatibility for active data paths.
- Never commit
.envor secrets. - Rotate any key accidentally exposed in logs/screenshots.
- Avoid logging secrets, preimages, private keys, or sensitive auth headers.
- For payment/relay logic changes, include failure-mode handling (timeout, retries, idempotency) in PR notes.
- Change is scoped to one concern
- Relevant tests pass locally
- No secrets committed
- Migrations included (if schema changed)
- Docs updated (if behavior/setup changed)
- Risk and rollback notes included for payment/contract changes
When filing a bug, include:
- Environment (
local,staging,testnet) - Expected behavior vs actual behavior
- Steps to reproduce
- Logs/error output (redacted)
- Related chain/asset/payment status if applicable
If requirements are unclear, open a draft PR early with assumptions listed. It is better to align early than rework critical payment logic late.