Coding Conventions
Consistent conventions make the codebase easier to read, maintain, and contribute to.
Git Workflow
Branch Naming
feature/VULCAN-123-add-user-authentication
bugfix/VULCAN-456-fix-login-redirect
hotfix/VULCAN-789-security-patchCommit Messages
We use Conventional Commits:
feat: add user authentication
fix: resolve login redirect issue
docs: update API documentation
refactor: simplify user service
test: add unit tests for auth module
chore: update dependenciesExamples:
bash
# Feature
git commit -m "feat: add JWT-based authentication"
# Bug fix with issue reference
git commit -m "fix: resolve login redirect loop
Fixes #123"
# Breaking change
git commit -m "feat!: change user API response format
BREAKING CHANGE: User response now includes nested profile object"Frontend Conventions
File Naming
| Type | Convention | Example |
|---|---|---|
| Components | PascalCase | LeadCard.tsx |
| Hooks | camelCase with use | useLeads.ts |
| Utilities | camelCase | formatDate.ts |
| Types | PascalCase | Lead.ts |
| Constants | SCREAMING_SNAKE | API_BASE_URL |
Component Structure
typescript
// 1. Imports (external, then internal)
import { useState } from 'react';
import { Button } from '@mui/material';
import { useLead } from '../hooks/useLead';
import type { Lead } from '../types';
// 2. Props interface above component
interface LeadCardProps {
lead: Lead;
onEdit: (id: string) => void;
}
// 3. Component with named export
export function LeadCard({ lead, onEdit }: LeadCardProps) {
// 4. Hooks at the top
const [isExpanded, setIsExpanded] = useState(false);
// 5. Early returns for edge cases
if (!lead) return null;
// 6. Main render
return (
<div>
{/* ... */}
</div>
);
}State Management
- Server state: TanStack Query for all API data
- Client state: Redux Toolkit for UI state only
- Form state: React Hook Form or local useState
Backend Conventions
Naming
| Type | Convention | Example |
|---|---|---|
| Commands | <Action><Feature>Command | CreateLeadCommand |
| Queries | <Action><Feature>Query | GetLeadQuery |
| Handlers | <Action><Feature>Handler | CreateLeadHandler |
| Responses | <Feature>Response | LeadResponse |
| Validators | <Action><Feature>Validator | CreateLeadValidator |
Database
| Type | Convention | Example |
|---|---|---|
| Tables | snake_case plural | leads, work_packages |
| Columns | snake_case | first_name, created_at |
| Primary Keys | id | id |
| Foreign Keys | [entity]_id | customer_id |
| Indexes | ix_[table]_[columns] | ix_leads_email |
Handler Structure
csharp
public class CreateLeadHandler : IRequestHandler<CreateLeadCommand, CreateLeadResponse>
{
private readonly AppDbContext _context;
public CreateLeadHandler(AppDbContext context)
{
_context = context;
}
public async ValueTask<CreateLeadResponse> Handle(
CreateLeadCommand request,
CancellationToken cancellationToken)
{
// 1. Validate (handled by FluentValidation pipeline)
// 2. Map to entity
var lead = new Lead
{
Name = request.Name,
Email = request.Email
};
// 3. Persist
_context.Leads.Add(lead);
await _context.SaveChangesAsync(cancellationToken);
// 4. Return response
return new CreateLeadResponse(lead.Id);
}
}Code Review Checklist
Before submitting a PR, ensure:
- [ ] Code follows naming conventions
- [ ] No commented-out code
- [ ] No console.log / Debug.WriteLine left in
- [ ] Tests pass locally
- [ ] Types are used (no
anyin TypeScript) - [ ] Error handling is appropriate
- [ ] No security vulnerabilities introduced
- [ ] PR description explains the change
Linting & Formatting
Frontend
bash
# Run ESLint
npm run lint
# Fix auto-fixable issues
npm run lint:fix
# Format with Prettier
npm run formatBackend
bash
# Format with dotnet format
dotnet format
# Analyze with Roslyn analyzers (automatic in build)
dotnet build