Contributing
Code standards, branch promotion, and PR process
This guide covers coding conventions, the branching strategy, and the pull request process for contributing to any Vezta subproject.
Code Standards
TypeScript
TypeScript strict mode is enabled across all subprojects. Write typed code throughout -- avoid any unless absolutely unavoidable.
- Path aliases:
@/*maps tosrc/*in the backend;@/maps to the project root in the frontend - Enums: Use
as constobjects instead of TypeScript enums (consistent with Kubb-generated types)
Linting and Formatting
- ESLint --
pnpm lintis currently broken in both subprojects (ESLint flat-config mismatch) and iscontinue-on-errorin CI. Use the real quality gates instead:pnpm buildfor the backend, andpnpm exec vitest run+tsc --noEmitfor the frontend. - Prettier -- run
pnpm formatin the backend for auto-formatting
cd vezta-be && pnpm lint # Backend ESLint (currently broken — flat-config mismatch)
cd vezta-fe && pnpm lint # Frontend ESLint via next lint (also broken — flat-config mismatch)Financial Values
Never use JavaScript floating-point numbers for financial values. The backend uses Prisma's Decimal type with specific precisions: @db.Decimal(18, 2) for USD amounts/volumes, @db.Decimal(10, 6) for prices, @db.Decimal(18, 6) for fees, @db.Decimal(5, 4) for rates. On the frontend, decimal values from the API arrive as strings -- parse them carefully.
Error Response Contract
All backend errors must normalize to this shape:
{
"statusCode": 400,
"code": "VALIDATION_ERROR",
"message": "Field 'amount' must be a positive number"
}The frontend depends on this contract. Use ApiException (not raw HttpException) for domain errors that need machine-readable codes.
Generated Code
Never hand-edit files in lib/api/gen/. This directory is fully regenerated by Kubb. To update the API client:
cd vezta-be && pnpm export:openapi # 1. Export spec
cd vezta-fe && pnpm generate # 2. Regen frontend client
# 3. Copy vezta-be/openapi.json → vezta-docs/public/openapi.json
cd vezta-docs && pnpm generate:api # 4. Regen API reference docsBranch Promotion
Promotion path is dev → staging → main:
dev-- integration branchstaging-- release candidatemain-- production
Branch naming for feature work:
feature/copy-trade-filters
fix/order-state-transition
refactor/market-normalizer
chore/upgrade-prisma
hotfix/cors-prod-bug
release/2026-04-30PRs target dev for normal feature work. Hotfixes can target staging or main directly.
| Target branch | Approvals required | What can merge in |
|---|---|---|
dev | 1 | Anything |
staging | 1 | dev, release/*, hotfix/* |
main | 2 | staging, hotfix/* |
A governance.yml (branch-promotion policy) and security.yml (CodeQL, dependency audit, secret scan) workflow live in each subproject's .github/workflows/ (the monorepo root is not itself a git repo). All CI checks must pass before merging.
Commit Messages
Use Conventional Commits:
feat: add copy trade subscription filters
fix: correct order state machine transition for partial fills
refactor: extract normalizer into standalone service
chore: upgrade Prisma to 6.x
docs: add API client generation guide
test: add E2E tests for trading endpointsInclude the scope when the change is specific to a subproject or module:
feat(trading): add TPSL support to order creation
fix(insider-signals): correct dedup TTL for vibrant modePull Request Process
Create a feature branch off dev
git checkout dev
git pull origin dev
git checkout -b feature/your-featureMake your changes
Follow the code standards. Run linting and tests locally.
Push and open a PR against dev
git push -u origin feature/your-featureInclude:
- A clear description of what the PR does and why
- Steps to test the changes
- Screenshots for UI changes
- A note if this requires a corresponding API client regeneration
CI checks
Workflows run automatically. All checks must pass before merging:
- Security gates (CodeQL, dep audit, secret scan)
- Linting
- Unit + E2E tests
- Branch governance (correct source branch)
Code review
Reviewers should check:
- Patterns and conventions match existing code
- Backend DTOs have proper
@ApiPropertydecorators (frontend codegen depends on this) - Financial calculations use
Decimal, never floats - Error responses use
ApiExceptionwith appropriate codes - Worker domain (
backgroundOnly([...], 'traders'|'market'|'misc')) is correctly tagged for new schedulers/processors - New env vars are documented (
vezta-be/.env.exampleand CLAUDE.md if cross-cutting)
Merge to dev → promote to staging → promote to main
- Merge to
dev— triggers Docker deploy ofvezta-fe-stagingto the staging VM and (eventually) staging backend deploy - Open a
dev → stagingPR. After it passes checks and a reviewer approves, merge. CI builds the backend image and deploys to staging. - After soak time on staging, open a
staging → mainPR. After 2 approvals + green CI, merge. The promoted-image production deploy uses the staging image -- no rebuild onmain.
Swagger Documentation
Every backend controller must be properly decorated for OpenAPI spec accuracy, since the frontend (and the docs site) generates from this spec:
@ApiTags('trading')
@ApiBearerAuth('access-token')
@Controller('api/v1/trading')
export class TradingController {
@Post('orders')
@ApiOperation({ summary: 'Place a new order' })
@ApiResponse({ status: 201, type: OrderResponseDto })
@ApiResponse({ status: 400, description: 'Validation error' })
create(@Body() dto: CreateOrderDto) { ... }
}After merging backend API changes to dev, run pnpm export:openapi (or rely on the auto-export at startup) and cd vezta-fe && pnpm generate so the frontend client matches before the next merge. The doc site has a separate pnpm generate:api step against public/openapi.json.