Coding Standards

This document outlines the coding standards and best practices for the Digibit ERP system development.

TypeScript/JavaScript Standards

Naming Conventions

  • Class names: PascalCase (e.g., UserService, CompanyComponent)
  • Method names: camelCase (e.g., getUserData(), validateForm())
  • Variable names: camelCase (e.g., currentUser, isLoading)
  • Constants: UPPER_SNAKE_CASE (e.g., MAX_RETRY_ATTEMPTS, DEFAULT_TIMEOUT)
  • Interfaces: PascalCase prefixed with 'I' (e.g., IUser, ICompany)
  • Enums: PascalCase (e.g., UserRole, DocumentStatus)

File Organization

  • Place imports at the top of the file in the following order:
  • Angular imports
  • Third-party library imports
  • Application imports
  • Relative imports
  • Group related functionality within files
  • Keep files focused on a single responsibility
  • Limit file length to approximately 300 lines when possible

Component Structure

// Example component structure
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-company-detail',
  templateUrl: './company-detail.component.html',
  styleUrls: ['./company-detail.component.scss']
})
export class CompanyDetailComponent implements OnInit {
  // Properties
  @Input() companyId: string;

  // Constructor
  constructor(private companyService: CompanyService) {}

  // Lifecycle hooks
  ngOnInit(): void {
    this.loadCompany();
  }

  // Public methods
  loadCompany(): void {
    // Implementation
  }

  // Private methods
  private validateCompany(company: any): boolean {
    // Implementation
  }
}

Service Structure

// Example service structure
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class CompanyService {
  private apiUrl = 'api/companies';

  constructor(private http: HttpClient) {}

  getCompanies(): Observable<ICompany[]> {
    return this.http.get<ICompany[]>(this.apiUrl);
  }

  getCompany(id: string): Observable<ICompany> {
    return this.http.get<ICompany>(`${this.apiUrl}/${id}`);
  }

  createCompany(company: ICompany): Observable<ICompany> {
    return this.http.post<ICompany>(this.apiUrl, company);
  }
}

HTML Template Standards

Structural Guidelines

  • Use semantic HTML elements where appropriate
  • Maintain consistent indentation (2 spaces)
  • Keep expressions simple in templates
  • Use property binding for dynamic values
  • Use event binding for user interactions

Accessibility

  • Include alt attributes for all images
  • Use proper heading hierarchy (h1, h2, h3, etc.)
  • Include label elements for form controls
  • Use ARIA attributes when necessary
  • Ensure sufficient color contrast

Example Template

<div class="company-card">
  <h2>{{ company.name }}</h2>
  <p>{{ company.description }}</p>
  <button 
    type="button" 
    class="btn btn-primary"
    (click)="onEditClick()"
    [disabled]="!canEdit">
    Edit
  </button>
</div>

SCSS/CSS Standards

Naming Convention

  • Use BEM (Block Element Modifier) methodology
  • Use kebab-case for class names
  • Prefix utility classes with 'u-'

Example SCSS

// Block
.company-card {
  border: 1px solid #ccc;
  padding: 1rem;

  // Element
  &__header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 1rem;
  }

  // Modifier
  &--featured {
    border-color: #007bff;
    box-shadow: 0 0.5rem 1rem rgba(0, 123, 255, 0.15);
  }
}

// Utility class
.u-hidden {
  display: none;
}

Error Handling

HTTP Requests

  • Always include error handling for HTTP requests
  • Use catchError operator in RxJS
  • Display user-friendly error messages
  • Log errors appropriately

Example Error Handling

getCompany(id: string): Observable<ICompany> {
  return this.http.get<ICompany>(`${this.apiUrl}/${id}`)
    .pipe(
      catchError(error => {
        console.error('Error fetching company:', error);
        return throwError('Could not fetch company data');
      })
    );
}

Performance Considerations

OnPush Change Detection

  • Use OnPush change detection strategy when possible
  • Immutably update objects and arrays
  • Use trackBy functions for *ngFor directives

Lazy Loading

  • Implement lazy loading for feature modules
  • Load data on demand rather than upfront
  • Use virtual scrolling for large datasets

Security Best Practices

Input Sanitization

  • Sanitize user inputs to prevent XSS attacks
  • Validate data on both client and server side
  • Use Angular's built-in sanitization where appropriate

Authentication

  • Implement proper authentication checks
  • Secure sensitive data transmission
  • Handle session expiration gracefully