Skip to content

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-patch

Commit 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 dependencies

Examples:

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

TypeConventionExample
ComponentsPascalCaseLeadCard.tsx
HookscamelCase with useuseLeads.ts
UtilitiescamelCaseformatDate.ts
TypesPascalCaseLead.ts
ConstantsSCREAMING_SNAKEAPI_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

TypeConventionExample
Commands<Action><Feature>CommandCreateLeadCommand
Queries<Action><Feature>QueryGetLeadQuery
Handlers<Action><Feature>HandlerCreateLeadHandler
Responses<Feature>ResponseLeadResponse
Validators<Action><Feature>ValidatorCreateLeadValidator

Database

TypeConventionExample
Tablessnake_case pluralleads, work_packages
Columnssnake_casefirst_name, created_at
Primary Keysidid
Foreign Keys[entity]_idcustomer_id
Indexesix_[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 any in 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 format

Backend

bash
# Format with dotnet format
dotnet format

# Analyze with Roslyn analyzers (automatic in build)
dotnet build

Built with VitePress | v1.1.0